From 8adc95a55ab51597cce665705c2a866294b743ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Oct 1997 09:12:41 +0000 Subject: This is a set of generic SMB client routines. I needed this in a hurry to fix the password server code, so I didn't use SMBlib. This code is fairly generic and uses a "struct cli_state" to hold the client state. (This used to be commit 3a0b5f06f42efdb522f1c5d3d9a4b4afabe03b40) --- source3/libsmb/clientgen.c | 673 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 673 insertions(+) create mode 100644 source3/libsmb/clientgen.c (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c new file mode 100644 index 0000000000..d47c5a2755 --- /dev/null +++ b/source3/libsmb/clientgen.c @@ -0,0 +1,673 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-1997 + + 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. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + + +extern int DEBUGLEVEL; + +/**************************************************************************** +setup basics in a outgoing packet +****************************************************************************/ +static void cli_setup_pkt(struct cli_state *cli) +{ + SSVAL(cli->outbuf,smb_pid,cli->pid); + SSVAL(cli->outbuf,smb_uid,cli->uid); + SSVAL(cli->outbuf,smb_mid,cli->mid); + if (cli->protocol > PROTOCOL_CORE) { + SCVAL(cli->outbuf,smb_flg,0x8); + SSVAL(cli->outbuf,smb_flg2,0x1); + } +} + + +/**************************************************************************** + send a SMB trans or trans2 request + ****************************************************************************/ +static BOOL cli_send_trans(struct cli_state *cli, + int trans, char *name, int fid, int flags, + char *data,char *param,uint16 *setup, int ldata,int lparam, + int lsetup,int mdata,int mparam,int msetup) +{ + int i; + int this_ldata,this_lparam; + int tot_data=0,tot_param=0; + char *outdata,*outparam; + char *p; + + this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */ + this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*SIZEOFWORD+this_lparam)); + + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,14+lsetup,0,True); + CVAL(cli->outbuf,smb_com) = trans; + SSVAL(cli->outbuf,smb_tid, cli->cnum); + cli_setup_pkt(cli); + + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3); + outdata = outparam+this_lparam; + + /* primary request */ + SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ + SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ + SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ + SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ + SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ + SSVAL(cli->outbuf,smb_flags,flags); /* flags */ + SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ + SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ + SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ + SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ + SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ + SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ + for (i=0;ioutbuf,smb_setup+i*SIZEOFWORD,setup[i]); + p = smb_buf(cli->outbuf); + if (trans==SMBtrans) { + strcpy(p,name); /* name[] */ + } else { + *p++ = 0; /* put in a null smb_name */ + *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ + } + if (this_lparam) /* param[] */ + memcpy(outparam,param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data,this_ldata); + set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + send_smb(cli->fd,cli->outbuf); + + if (this_ldata < ldata || this_lparam < lparam) { + /* receive interim response */ + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || + CVAL(cli->inbuf,smb_rcls) != 0) { + return(False); + } + + tot_data = this_ldata; + tot_param = this_lparam; + + while (tot_data < ldata || tot_param < lparam) { + this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ + this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); + + set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); + CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; + + outparam = smb_buf(cli->outbuf); + outdata = outparam+this_lparam; + + /* secondary request */ + SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ + SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ + SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ + SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ + SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ + SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ + SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ + SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ + if (trans==SMBtrans2) + SSVAL(cli->outbuf,smb_sfid,fid); /* fid */ + if (this_lparam) /* param[] */ + memcpy(outparam,param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data,this_ldata); + set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + send_smb(cli->fd,cli->outbuf); + + tot_data += this_ldata; + tot_param += this_lparam; + } + } + + return(True); +} + + +/**************************************************************************** + receive a SMB trans or trans2 response allocating the necessary memory + ****************************************************************************/ +static BOOL cli_receive_trans(struct cli_state *cli, + int trans,int *data_len, + int *param_len, char **data,char **param) +{ + int total_data=0; + int total_param=0; + int this_data,this_param; + + *data_len = *param_len = 0; + + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != trans) { + DEBUG(0,("Expected %s response, got command 0x%02x\n", + trans==SMBtrans?"SMBtrans":"SMBtrans2", + CVAL(cli->inbuf,smb_com))); + return(False); + } + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); + + /* parse out the lengths */ + total_data = SVAL(cli->inbuf,smb_tdrcnt); + total_param = SVAL(cli->inbuf,smb_tprcnt); + + /* allocate it */ + *data = Realloc(*data,total_data); + *param = Realloc(*param,total_param); + + while (1) { + this_data = SVAL(cli->inbuf,smb_drcnt); + this_param = SVAL(cli->inbuf,smb_prcnt); + + if (this_data + *data_len > total_data || + this_param + *param_len > total_param) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) + memcpy(*data + SVAL(cli->inbuf,smb_drdisp), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), + this_data); + if (this_param) + memcpy(*param + SVAL(cli->inbuf,smb_prdisp), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), + this_param); + *data_len += this_data; + *param_len += this_param; + + /* parse out the total lengths again - they can shrink! */ + total_data = SVAL(cli->inbuf,smb_tdrcnt); + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != trans) { + DEBUG(0,("Expected %s response, got command 0x%02x\n", + trans==SMBtrans?"SMBtrans":"SMBtrans2", + CVAL(cli->inbuf,smb_com))); + return(False); + } + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); + } + + return(True); +} + + +/**************************************************************************** +call a remote api +****************************************************************************/ +static BOOL cli_api(struct cli_state *cli, + int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, + int *rdrcnt, char *param,char *data, + char **rparam, char **rdata) +{ + cli_send_trans(cli,SMBtrans,"\\PIPE\\LANMAN",0,0, + data,param,NULL, + drcnt,prcnt,0, + mdrcnt,mprcnt,0); + + return (cli_receive_trans(cli,SMBtrans, + rdrcnt,rprcnt, + rdata,rparam)); +} + + +/**************************************************************************** +perform a NetWkstaUserLogon +****************************************************************************/ +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + pstring param; + + memset(param, 0, sizeof(param)); + + /* send a SMBtrans command with api NetWkstaUserLogon */ + p = param; + SSVAL(p,0,132); /* api number */ + p += 2; + strcpy(p,"OOWb54WrLh"); + p = skip_string(p,1); + strcpy(p,"WB21BWDWWDDDDDDDzzzD"); + p = skip_string(p,1); + SSVAL(p,0,1); + p += 2; + strcpy(p,user); + strupper(p); + p += 21; p++; p += 15; p++; + strcpy(p, workstation); + strupper(p); + p += 16; + SSVAL(p, 0, BUFFER_SIZE); + p += 2; + SSVAL(p, 0, BUFFER_SIZE); + p += 2; + + cli->error = -1; + + if (cli_api(cli, PTR_DIFF(p,param),0, + 1024,BUFFER_SIZE, + &rprcnt,&rdrcnt, + param,NULL, + &rparam,&rdata)) { + cli->error = SVAL(rparam,0); + p = rdata; + + if (cli->error == 0) { + DEBUG(4,("NetWkstaUserLogon success\n")); + cli->privilages = SVAL(p, 24); + fstrcpy(cli->eff_name,p+2); + } else { + DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); + } + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + return cli->error == 0; +} + + + +static struct { + int prot; + char *name; + } +prots[] = + { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {-1,NULL} + }; + + +/**************************************************************************** +send a session setup +****************************************************************************/ +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup) +{ + char *p; + fstring pword; + + if (cli->protocol < PROTOCOL_LANMAN1) + return False; + + if (passlen > sizeof(pword)-1) { + return False; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} + + /* send a session setup command */ + bzero(cli->outbuf,smb_size); + + if (cli->protocol < PROTOCOL_NT1) { + set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_pkt(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,1); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + strcpy(p,user); + strupper(p); + } else { + set_message(cli->outbuf,13,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_pkt(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += SVAL(cli->outbuf,smb_vwv7); + memcpy(p,ntpass,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); + strcpy(p,user); + strupper(p); + p = skip_string(p,1); + strcpy(p,workgroup); + strupper(p); + p = skip_string(p,1); + strcpy(p,"Unix");p = skip_string(p,1); + strcpy(p,"Samba");p = skip_string(p,1); + set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + } + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + /* use the returned uid from now on */ + cli->uid = SVAL(cli->inbuf,smb_uid); + + return True; +} + + +/**************************************************************************** +send a tconX +****************************************************************************/ +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pword, int passlen) +{ + char *p; + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,4, + 2 + strlen(share) + passlen + strlen(dev),True); + CVAL(cli->outbuf,smb_com) = SMBtconX; + cli_setup_pkt(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv3,passlen); + + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + strcpy(p,share); + p = skip_string(p,1); + strcpy(p,dev); + + SCVAL(cli->inbuf,smb_rcls, 1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + cli->cnum = SVAL(cli->inbuf,smb_tid); + return True; +} + + +/**************************************************************************** +send a tree disconnect +****************************************************************************/ +BOOL cli_tdis(struct cli_state *cli) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBtdis; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_pkt(cli); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + return CVAL(cli->inbuf,smb_rcls) == 0; +} + + +/**************************************************************************** +send a negprot command +****************************************************************************/ +BOOL cli_negprot(struct cli_state *cli) +{ + char *p; + int numprots; + int plength; + + bzero(cli->outbuf,smb_size); + + /* setup the protocol strings */ + for (plength=0,numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) + plength += strlen(prots[numprots].name)+2; + + set_message(cli->outbuf,0,plength,True); + + p = smb_buf(cli->outbuf); + for (numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) { + *p++ = 2; + strcpy(p,prots[numprots].name); + p += strlen(p) + 1; + } + + CVAL(cli->outbuf,smb_com) = SMBnegprot; + cli_setup_pkt(cli); + + CVAL(smb_buf(cli->outbuf),0) = 2; + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + if (CVAL(cli->inbuf,smb_rcls) != 0 || + ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { + return(False); + } + + cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + + + if (cli->protocol < PROTOCOL_NT1) { + cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->sesskey = IVAL(cli->inbuf,smb_vwv6); + cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + if (cli->protocol >= PROTOCOL_COREPLUS) { + cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); + } + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + } else { + /* NT protocol */ + cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); + cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); + cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; + /* this time arrives in real GMT */ + cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + if (IVAL(cli->inbuf,smb_vwv9+1) & 1) + cli->readbraw_supported = + cli->writebraw_supported = True; + } + + return True; +} + + +/**************************************************************************** + send a session request +****************************************************************************/ +BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, + char *myname) +{ + fstring dest; + char *p; + int len = 4; + /* send a session request (RFC 1002) */ + + fstrcpy(dest,host); + + p = strchr(dest,'.'); + if (p) *p = 0; + + fstrcpy(cli->desthost, dest); + + /* put in the destination name */ + p = cli->outbuf+len; + name_mangle(dest,p,name_type); + len += name_len(p); + + /* and my name */ + p = cli->outbuf+len; + name_mangle(myname,p,0); + len += name_len(p); + + /* setup the packet length */ + _smb_setlen(cli->outbuf,len); + CVAL(cli->outbuf,0) = 0x81; + + send_smb(cli->fd,cli->outbuf); + DEBUG(5,("Sent session request\n")); + + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + if (CVAL(cli->inbuf,0) != 0x82) { + cli->error = CVAL(cli->inbuf,0); + return False; + } + return(True); +} + + +/**************************************************************************** +open the client sockets +****************************************************************************/ +BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) +{ + struct in_addr dest_ip; + + fstrcpy(cli->desthost, host); + + if (!ip) { + struct hostent *hp; + + if ((hp = Get_Hostbyname(cli->desthost)) == 0) { + return False; + } + + putip((char *)&dest_ip,(char *)hp->h_addr); + } else { + dest_ip = *ip; + } + + + cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); + if (cli->fd == -1) + return False; + + return True; +} + + +/**************************************************************************** +initialise a client structure +****************************************************************************/ +BOOL cli_initialise(struct cli_state *cli) +{ + if (cli->initialised) cli_shutdown(cli); + + memset(cli, 0, sizeof(*cli)); + cli->fd = -1; + cli->cnum = -1; + cli->pid = getpid(); + cli->mid = 1; + cli->uid = getuid(); + cli->protocol = PROTOCOL_NT1; + cli->timeout = 20000; + cli->bufsize = 0x10000; + cli->max_xmit = cli->bufsize - 4; + cli->outbuf = (char *)malloc(cli->bufsize); + cli->inbuf = (char *)malloc(cli->bufsize); + if (!cli->outbuf || !cli->inbuf) return False; + cli->initialised = 1; + return True; +} + +/**************************************************************************** +shutdown a client structure +****************************************************************************/ +void cli_shutdown(struct cli_state *cli) +{ + if (cli->outbuf) free(cli->outbuf); + if (cli->inbuf) free(cli->inbuf); + if (cli->fd != -1) close(cli->fd); + memset(cli, 0, sizeof(*cli)); +} -- cgit From 5557ab3c007b79c132e9a2da16e41be7b13f1b39 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 23 Oct 1997 19:27:53 +0000 Subject: renamed static cli_setup_pkt() to static cli_setup_packet() because it clashed with the currently-used cli_setup_pkt() in clientutil.c (This used to be commit 25560cf40b997e400d16fa0c1380e5bc29c015a5) --- source3/libsmb/clientgen.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d47c5a2755..7cd2ef6903 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,7 +31,7 @@ extern int DEBUGLEVEL; /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ -static void cli_setup_pkt(struct cli_state *cli) +static void cli_setup_packet(struct cli_state *cli) { SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->uid); @@ -64,7 +64,7 @@ static BOOL cli_send_trans(struct cli_state *cli, set_message(cli->outbuf,14+lsetup,0,True); CVAL(cli->outbuf,smb_com) = trans; SSVAL(cli->outbuf,smb_tid, cli->cnum); - cli_setup_pkt(cli); + cli_setup_packet(cli); outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3); outdata = outparam+this_lparam; @@ -367,7 +367,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->protocol < PROTOCOL_NT1) { set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_pkt(cli); + cli_setup_packet(cli); CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); @@ -383,7 +383,7 @@ BOOL cli_session_setup(struct cli_state *cli, } else { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_pkt(cli); + cli_setup_packet(cli); CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE); @@ -438,7 +438,7 @@ BOOL cli_send_tconX(struct cli_state *cli, set_message(cli->outbuf,4, 2 + strlen(share) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; - cli_setup_pkt(cli); + cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv3,passlen); @@ -474,7 +474,7 @@ BOOL cli_tdis(struct cli_state *cli) set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBtdis; SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_pkt(cli); + cli_setup_packet(cli); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) @@ -513,7 +513,7 @@ BOOL cli_negprot(struct cli_state *cli) } CVAL(cli->outbuf,smb_com) = SMBnegprot; - cli_setup_pkt(cli); + cli_setup_packet(cli); CVAL(smb_buf(cli->outbuf),0) = 2; -- cgit From a342ff5bf407679918a1a5d0c2faaf0a3465d303 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Oct 1997 07:32:02 +0000 Subject: The browse synchronisation code in nmbsync.c now uses the clientgen.c code, which means we don't have to link with a fake getpass routine and we don't have a whole pile of global variables that really have nothing to do with nmbd and were there to keep the client code happy. The code should function identically to what it did before (hopefully it was correct) The only thing that now uses the horrible clientutil.c code is smbclient. (This used to be commit 4bf5c03b18f88b566f3ac12cc4b3a9c5c96fd35d) --- source3/libsmb/clientgen.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7cd2ef6903..b6ad1611ac 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -313,6 +313,79 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) } +/**************************************************************************** +call a NetServerEnum for the specified workgroup and servertype mask. +This function then calls the specified callback function for each name returned. + +The callback function takes 3 arguments: the machine name, the server type and +the comment. +****************************************************************************/ +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(char *, uint32, char *)) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + pstring param; + int uLevel = 1; + int count = -1; + + /* send a SMBtrans command with api NetServerEnum */ + p = param; + SSVAL(p,0,0x68); /* api number */ + p += 2; + strcpy(p,"WrLehDz"); + p = skip_string(p,1); + + strcpy(p,"B16BBDz"); + + p = skip_string(p,1); + SSVAL(p,0,uLevel); + SSVAL(p,2,BUFFER_SIZE); + p += 4; + SIVAL(p,0,stype); + p += 4; + + pstrcpy(p, workgroup); + p = skip_string(p,1); + + if (cli_api(cli, + PTR_DIFF(p,param), /* param count */ + 8, /*data count */ + 0, /* mprcount */ + BUFFER_SIZE, /* mdrcount */ + &rprcnt,&rdrcnt, + param, NULL, + &rparam,&rdata)) { + int res = SVAL(rparam,0); + int converter=SVAL(rparam,2); + int i; + + if (res == 0) { + count=SVAL(rparam,4); + p = rdata; + + for (i = 0;i < count;i++, p += 26) { + char *sname = p; + int comment_offset = IVAL(p,22) & 0xFFFF; + char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + + stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + + fn(sname, stype, cmnt); + } + } + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return(count > 0); +} + + + static struct { int prot; -- cgit From 224c40a52335bf1afc7662183900e143307aa5be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 1 Nov 1997 13:22:16 +0000 Subject: a simple SMB torture tester. This will allow us to evaluate locking techniques more accurately. (This used to be commit 054e3b2ae3a8cfb98fde72becef9b05de34d2ba7) --- source3/libsmb/clientgen.c | 334 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 331 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b6ad1611ac..b2ecb07ded 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -502,14 +502,29 @@ BOOL cli_session_setup(struct cli_state *cli, send a tconX ****************************************************************************/ BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pword, int passlen) + char *share, char *dev, char *pass, int passlen) { + fstring fullshare, pword; char *p; bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); + if (cli->sec_mode & 1) { + passlen = 1; + pass = ""; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + + sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + set_message(cli->outbuf,4, - 2 + strlen(share) + passlen + strlen(dev),True); + 2 + strlen(fullshare) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -519,7 +534,7 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,share); + strcpy(p,fullshare); p = skip_string(p,1); strcpy(p,dev); @@ -556,6 +571,294 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +/**************************************************************************** +delete a file +****************************************************************************/ +BOOL cli_unlink(struct cli_state *cli, char *fname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,1, 2 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBunlink; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + + +/**************************************************************************** +open a file +****************************************************************************/ +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn=0; + unsigned accessmode=0; + + if (flags & O_CREAT) + openfn |= (1<<4); + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) + openfn |= (1<<1); + else + openfn |= (1<<0); + } + + accessmode = (share_mode<<4); + + if ((flags & O_RDWR) == O_RDWR) { + accessmode |= 2; + } else if ((flags & O_WRONLY) == O_WRONLY) { + accessmode |= 1; + } + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,15,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBopenX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + SSVAL(cli->outbuf,smb_vwv3,accessmode); + SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv8,openfn); + + p = smb_buf(cli->outbuf); + strcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2); +} + + + + +/**************************************************************************** + close a file +****************************************************************************/ +BOOL cli_close(struct cli_state *cli, int fnum) +{ + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,3,0,True); + + CVAL(cli->outbuf,smb_com) = SMBclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SSVAL(cli->outbuf,smb_vwv1,0); + SSVAL(cli->outbuf,smb_vwv2,0); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** + lock a file +****************************************************************************/ +BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** + unlock a file +****************************************************************************/ +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,1); + SSVAL(cli->outbuf,smb_vwv7,0); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** + read from a file +****************************************************************************/ +int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size = SVAL(cli->inbuf, smb_vwv5); + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + + memcpy(buf, p, size); + + return size; +} + + +/**************************************************************************** + write to a file +****************************************************************************/ +int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,12,size,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + + SSVAL(cli->outbuf,smb_vwv10,size); + SSVAL(cli->outbuf,smb_vwv11,smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf, size); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf, smb_vwv2); +} + /**************************************************************************** send a negprot command @@ -744,3 +1047,28 @@ void cli_shutdown(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } + +/**************************************************************************** + return a description of the error +****************************************************************************/ +char *cli_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/**************************************************************************** + return error codes for the last packet +****************************************************************************/ +void cli_error(struct cli_state *cli, int *eclass, int *num) +{ + *eclass = CVAL(cli->inbuf,smb_rcls); + *num = SVAL(cli->inbuf,smb_err); +} + +/**************************************************************************** +set socket options on a open connection +****************************************************************************/ +void cli_sockopt(struct cli_state *cli, char *options) +{ + set_socket_options(cli->fd, options); +} -- cgit From a90d2061316d19c30d9f14c1e78d6f6266183ce0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Nov 1997 04:02:05 +0000 Subject: added two more sets of tests to the smbtorture test. The tests I added are ones that I know Samba fails. They are: 1) correct support for retaining locks over a close (ie. the server must not use posix semantics) 2) support for lock timeouts 3) the server supports multiple locking contexts on the one SMB connection, distinguished by PID. 4) the server correctly fails overlapping locks made by the same PID (this goes against POSIX behaviour, which is why it is tricky to implement) 5) the server denies unlock requests by an incorrect client PID I've been discussing with Jeremy ways that we can re-implement the locking code to handle these correctly. This test code will be useful to see that we have got it right. (This used to be commit 097781e2992f12c545170c82ada2f4023a9784f5) --- source3/libsmb/clientgen.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b2ecb07ded..b98f2fca69 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1072,3 +1072,13 @@ void cli_sockopt(struct cli_state *cli, char *options) { set_socket_options(cli->fd, options); } + +/**************************************************************************** +set the PID to use for smb messages. Return the old pid. +****************************************************************************/ +int cli_setpid(struct cli_state *cli, int pid) +{ + int ret = cli->pid; + cli->pid = pid; + return ret; +} -- cgit From e357d9106895b165bfa3f8331b9f186004c9a6cd Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 9 Nov 1997 17:30:10 +0000 Subject: attempting to mark up 32 bit error codes, needed for NT domains. separated out smb server-mode password validation into a separate file. added called and calling netbios names to client gen state: referenced section in rfc1002.txt. created workstation trust account checking code in ntclient.c there might be a bug in reply_session_setup_andX. i indented and added { } around single-line if statements: the lm password checking code now doesn't look right (around the GUEST_SESSSETUP bits). *no code semantics have been changed by the indentation process*. (This used to be commit f27966957fa7f16d337a4a58719239d036deab4c) --- source3/libsmb/clientgen.c | 146 +++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 64 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b98f2fca69..78bbf8115f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,7 @@ static BOOL cli_send_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || - CVAL(cli->inbuf,smb_rcls) != 0) { + cli_error(cli,NULL, NULL)) { return(False); } @@ -176,8 +176,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) - return(False); + if (cli_error(cli,NULL, NULL)) return(False); /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -227,8 +226,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) - return(False); + if (cli_error(cli,NULL, NULL)) return(False); } return(True); @@ -300,7 +298,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privilages = SVAL(p, 24); + cli->privileges = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); @@ -424,15 +422,22 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) + { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } else { + } + else + { memcpy(pword, pass, passlen); } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} + if (!(cli->sec_mode & USE_USER_LEVEL_SECURITY)) + { + fstrcpy(pword, ""); + passlen=1; + } /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -487,9 +492,7 @@ BOOL cli_session_setup(struct cli_state *cli, show_msg(cli->inbuf); - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return(False); /* use the returned uid from now on */ cli->uid = SVAL(cli->inbuf,smb_uid); @@ -509,19 +512,19 @@ BOOL cli_send_tconX(struct cli_state *cli, bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - if (cli->sec_mode & 1) { + if (cli->sec_mode & USE_USER_LEVEL_SECURITY) { passlen = 1; pass = ""; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); } else { memcpy(pword, pass, passlen); } - sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + sprintf(fullshare, "\\\\%s\\%s", cli->called_netbios_name, share); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); @@ -544,9 +547,7 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return(False); cli->cnum = SVAL(cli->inbuf,smb_tid); return True; @@ -568,7 +569,7 @@ BOOL cli_tdis(struct cli_state *cli) if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - return CVAL(cli->inbuf,smb_rcls) == 0; + return !cli_error(cli,NULL, NULL); } /**************************************************************************** @@ -599,9 +600,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -659,9 +658,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + if (cli_error(cli,NULL, NULL)) return -1; return SVAL(cli->inbuf,smb_vwv2); } @@ -692,9 +689,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -733,9 +728,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -773,9 +766,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -808,9 +799,7 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + if (cli_error(cli,NULL, NULL)) return -1; size = SVAL(cli->inbuf, smb_vwv5); p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); @@ -852,9 +841,7 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + if (cli_error(cli,NULL, NULL)) return -1; return SVAL(cli->inbuf, smb_vwv2); } @@ -899,10 +886,8 @@ BOOL cli_negprot(struct cli_state *cli) show_msg(cli->inbuf); - if (CVAL(cli->inbuf,smb_rcls) != 0 || - ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { - return(False); - } + if (cli_error(cli,NULL, NULL)) return False; + if ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots) return(False); cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; @@ -936,33 +921,43 @@ BOOL cli_negprot(struct cli_state *cli) return True; } +#define TRUNCATE_NETBIOS_NAME 1 /**************************************************************************** - send a session request + send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname) +BOOL cli_session_request(struct cli_state *cli, + char *called_host_name , int called_name_type, + char calling_netbios_name[16], int calling_name_type) { - fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - fstrcpy(dest,host); + strncpy(cli->called_netbios_name , called_host_name , sizeof(cli->called_netbios_name )); + strncpy(cli->calling_netbios_name, calling_netbios_name, sizeof(cli->calling_netbios_name)); - p = strchr(dest,'.'); + /* sorry, don't trust strncpy to null-terminate the string... */ + cli->called_netbios_name [sizeof(cli->called_netbios_name )-1] = 0; + cli->calling_netbios_name[sizeof(cli->calling_netbios_name)-1] = 0; + +#ifdef TRUNCATE_NETBIOS_NAME + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' + */ + p = strchr(cli->called_netbios_name, '.'); if (p) *p = 0; - - fstrcpy(cli->desthost, dest); +#endif /* TRUNCATE_NETBIOS_NAME */ /* put in the destination name */ p = cli->outbuf+len; - name_mangle(dest,p,name_type); + name_mangle(cli->called_netbios_name, p, called_name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(myname,p,0); + name_mangle(cli->calling_netbios_name, p, calling_name_type); len += name_len(p); /* setup the packet length */ @@ -990,26 +985,27 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { struct in_addr dest_ip; - fstrcpy(cli->desthost, host); + fstrcpy(cli->full_dest_host_name, host); - if (!ip) { + if (!ip) + { + /* no ip specified - look up the name */ struct hostent *hp; - if ((hp = Get_Hostbyname(cli->desthost)) == 0) { + if ((hp = Get_Hostbyname(host)) == 0) { return False; } putip((char *)&dest_ip,(char *)hp->h_addr); } else { + /* use the given ip address */ dest_ip = *ip; } - + /* open the socket */ cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); - if (cli->fd == -1) - return False; - return True; + return (cli->fd != -1); } @@ -1059,10 +1055,32 @@ char *cli_errstr(struct cli_state *cli) /**************************************************************************** return error codes for the last packet ****************************************************************************/ -void cli_error(struct cli_state *cli, int *eclass, int *num) +BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - *eclass = CVAL(cli->inbuf,smb_rcls); - *num = SVAL(cli->inbuf,smb_err); + int flgs2 = SVAL(cli->inbuf,smb_flg2); + + if (eclass) *eclass = 0; + if (num ) *num = 0; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { + /* 32 bit error codes detected */ + uint32 nt_err = IVAL(cli->inbuf,smb_rcls); + if (num) *num = nt_err; + return (nt_err != 0); + } + else + { + /* dos 16 bit error codes detected */ + char rcls = CVAL(cli->inbuf,smb_rcls); + if (rcls != 0) + { + if (eclass) *eclass = rcls; + if (num ) *num = SVAL(cli->inbuf,smb_err); + return True; + } + } + return False; } /**************************************************************************** -- cgit From 77aec4ae6307c0ad0b843bbf23d64ccb1aaf7476 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Nov 1997 19:23:17 +0000 Subject: Rolled back tree state to 11:59pm 8th November 1997 EST to remove problems. Jeremy (This used to be commit 4a36ac236c2ad634f05efcd0179875d09988614a) --- source3/libsmb/clientgen.c | 146 ++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 82 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 78bbf8115f..b98f2fca69 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,7 @@ static BOOL cli_send_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || - cli_error(cli,NULL, NULL)) { + CVAL(cli->inbuf,smb_rcls) != 0) { return(False); } @@ -176,7 +176,8 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -226,7 +227,8 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); } return(True); @@ -298,7 +300,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privileges = SVAL(p, 24); + cli->privilages = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); @@ -422,22 +424,15 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) - { + if ((cli->sec_mode & 2) && *pass && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } - else - { + } else { memcpy(pword, pass, passlen); } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & USE_USER_LEVEL_SECURITY)) - { - fstrcpy(pword, ""); - passlen=1; - } + if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -492,7 +487,9 @@ BOOL cli_session_setup(struct cli_state *cli, show_msg(cli->inbuf); - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } /* use the returned uid from now on */ cli->uid = SVAL(cli->inbuf,smb_uid); @@ -512,19 +509,19 @@ BOOL cli_send_tconX(struct cli_state *cli, bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - if (cli->sec_mode & USE_USER_LEVEL_SECURITY) { + if (cli->sec_mode & 1) { passlen = 1; pass = ""; } - if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) { + if ((cli->sec_mode & 2) && *pass && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); } else { memcpy(pword, pass, passlen); } - sprintf(fullshare, "\\\\%s\\%s", cli->called_netbios_name, share); + sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); @@ -547,7 +544,9 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } cli->cnum = SVAL(cli->inbuf,smb_tid); return True; @@ -569,7 +568,7 @@ BOOL cli_tdis(struct cli_state *cli) if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - return !cli_error(cli,NULL, NULL); + return CVAL(cli->inbuf,smb_rcls) == 0; } /**************************************************************************** @@ -600,7 +599,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -658,7 +659,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) return -1; } - if (cli_error(cli,NULL, NULL)) return -1; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } return SVAL(cli->inbuf,smb_vwv2); } @@ -689,7 +692,9 @@ BOOL cli_close(struct cli_state *cli, int fnum) return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -728,7 +733,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -766,7 +773,9 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -799,7 +808,9 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s return -1; } - if (cli_error(cli,NULL, NULL)) return -1; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } size = SVAL(cli->inbuf, smb_vwv5); p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); @@ -841,7 +852,9 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 return -1; } - if (cli_error(cli,NULL, NULL)) return -1; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } return SVAL(cli->inbuf, smb_vwv2); } @@ -886,8 +899,10 @@ BOOL cli_negprot(struct cli_state *cli) show_msg(cli->inbuf); - if (cli_error(cli,NULL, NULL)) return False; - if ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0 || + ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { + return(False); + } cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; @@ -921,43 +936,33 @@ BOOL cli_negprot(struct cli_state *cli) return True; } -#define TRUNCATE_NETBIOS_NAME 1 /**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 + send a session request ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, - char *called_host_name , int called_name_type, - char calling_netbios_name[16], int calling_name_type) +BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, + char *myname) { + fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - strncpy(cli->called_netbios_name , called_host_name , sizeof(cli->called_netbios_name )); - strncpy(cli->calling_netbios_name, calling_netbios_name, sizeof(cli->calling_netbios_name)); + fstrcpy(dest,host); - /* sorry, don't trust strncpy to null-terminate the string... */ - cli->called_netbios_name [sizeof(cli->called_netbios_name )-1] = 0; - cli->calling_netbios_name[sizeof(cli->calling_netbios_name)-1] = 0; - -#ifdef TRUNCATE_NETBIOS_NAME - /* ok. this is because of a stupid microsoft-ism. if the called host - name contains a '.', microsoft clients expect you to truncate the - netbios name up to and including the '.' - */ - p = strchr(cli->called_netbios_name, '.'); + p = strchr(dest,'.'); if (p) *p = 0; -#endif /* TRUNCATE_NETBIOS_NAME */ + + fstrcpy(cli->desthost, dest); /* put in the destination name */ p = cli->outbuf+len; - name_mangle(cli->called_netbios_name, p, called_name_type); + name_mangle(dest,p,name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(cli->calling_netbios_name, p, calling_name_type); + name_mangle(myname,p,0); len += name_len(p); /* setup the packet length */ @@ -985,27 +990,26 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { struct in_addr dest_ip; - fstrcpy(cli->full_dest_host_name, host); + fstrcpy(cli->desthost, host); - if (!ip) - { - /* no ip specified - look up the name */ + if (!ip) { struct hostent *hp; - if ((hp = Get_Hostbyname(host)) == 0) { + if ((hp = Get_Hostbyname(cli->desthost)) == 0) { return False; } putip((char *)&dest_ip,(char *)hp->h_addr); } else { - /* use the given ip address */ dest_ip = *ip; } - /* open the socket */ + cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); + if (cli->fd == -1) + return False; - return (cli->fd != -1); + return True; } @@ -1055,32 +1059,10 @@ char *cli_errstr(struct cli_state *cli) /**************************************************************************** return error codes for the last packet ****************************************************************************/ -BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +void cli_error(struct cli_state *cli, int *eclass, int *num) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); - - if (eclass) *eclass = 0; - if (num ) *num = 0; - - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) - { - /* 32 bit error codes detected */ - uint32 nt_err = IVAL(cli->inbuf,smb_rcls); - if (num) *num = nt_err; - return (nt_err != 0); - } - else - { - /* dos 16 bit error codes detected */ - char rcls = CVAL(cli->inbuf,smb_rcls); - if (rcls != 0) - { - if (eclass) *eclass = rcls; - if (num ) *num = SVAL(cli->inbuf,smb_err); - return True; - } - } - return False; + *eclass = CVAL(cli->inbuf,smb_rcls); + *num = SVAL(cli->inbuf,smb_err); } /**************************************************************************** -- cgit From 5b6d9d4376ff163a4ee4b4e7a7939c56e5394ffb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Nov 1997 02:38:54 +0000 Subject: fixed a bug which caused nmbd to core dump. The problem was incorrect parameters to cli_NetServerEnum() (This used to be commit 628d5895aa8a6add1a76bcf2561d01881b7c8c63) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b98f2fca69..66d54a9b99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -352,8 +352,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, if (cli_api(cli, PTR_DIFF(p,param), /* param count */ - 8, /*data count */ - 0, /* mprcount */ + 0, /*data count */ + 8, /* mprcount */ BUFFER_SIZE, /* mdrcount */ &rprcnt,&rdrcnt, param, NULL, -- cgit From 8bf0f359f3ec440ace0bba6c12ca65d25ba45fd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 02:41:22 +0000 Subject: added a test for the NT SMBgetatr bug in smbtorture added support for choosing the protocol level in smbtorture (-m option) use -1 for null date in cli_close() get the attributes right in cli_open() (This used to be commit d64d40a6ec57a4a999ae1f39175bcfd86ccb196e) --- source3/libsmb/clientgen.c | 78 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 19 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 66d54a9b99..031c0c10de 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -368,8 +368,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, for (i = 0;i < count;i++, p += 26) { char *sname = p; - int comment_offset = IVAL(p,22) & 0xFFFF; - char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; + char *cmnt = comment_offset?(rdata+comment_offset):""; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; @@ -418,7 +419,7 @@ BOOL cli_session_setup(struct cli_state *cli, fstring pword; if (cli->protocol < PROTOCOL_LANMAN1) - return False; + return True; if (passlen > sizeof(pword)-1) { return False; @@ -647,7 +648,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ SSVAL(cli->outbuf,smb_vwv3,accessmode); SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); @@ -684,8 +685,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,fnum); - SSVAL(cli->outbuf,smb_vwv1,0); - SSVAL(cli->outbuf,smb_vwv2,0); + SIVALS(cli->outbuf,smb_vwv1,-1); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -860,6 +860,44 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 } +/**************************************************************************** +stat a file (actually a SMBgetattr call) +This only fills in a few of the stat fields +****************************************************************************/ +BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0,strlen(fname)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBgetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p = 4; + strcpy(p+1, fname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + memset(st, 0, sizeof(*st)); + st->st_size = IVAL(cli->inbuf, smb_vwv3); + + st->st_mtime = make_unix_date3(cli->inbuf+smb_vwv1); + return True; +} + + /**************************************************************************** send a negprot command ****************************************************************************/ @@ -907,19 +945,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol < PROTOCOL_NT1) { - cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); - cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); - cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; - /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); - if (cli->protocol >= PROTOCOL_COREPLUS) { - cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); - cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - } - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - } else { + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); @@ -931,6 +957,20 @@ BOOL cli_negprot(struct cli_state *cli) if (IVAL(cli->inbuf,smb_vwv9+1) & 1) cli->readbraw_supported = cli->writebraw_supported = True; + } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->sesskey = IVAL(cli->inbuf,smb_vwv6); + cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + } else { + /* the old core protocol */ + cli->sec_mode = 0; + cli->serverzone = TimeDiff(time(NULL)); } return True; -- cgit From a1c5442abb3bc221157ca3620d35e1a013b26232 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 03:09:59 +0000 Subject: test SMBsetatr as well (This used to be commit 2f29c24ba721e417828efca57011ed45892191a5) --- source3/libsmb/clientgen.c | 57 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 031c0c10de..39d1226f9d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -861,10 +861,10 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 /**************************************************************************** -stat a file (actually a SMBgetattr call) -This only fills in a few of the stat fields +do a SMBgetatr call ****************************************************************************/ -BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) +BOOL cli_getatr(struct cli_state *cli, char *fname, + int *attr, uint32 *size, time_t *t) { char *p; @@ -890,10 +890,55 @@ BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) return False; } - memset(st, 0, sizeof(*st)); - st->st_size = IVAL(cli->inbuf, smb_vwv3); + if (size) { + *size = IVAL(cli->inbuf, smb_vwv3); + } + + if (t) { + *t = make_unix_date3(cli->inbuf+smb_vwv1); + } + + if (attr) { + *attr = SVAL(cli->inbuf,smb_vwv0); + } + + + return True; +} + + +/**************************************************************************** +do a SMBsetatr call +****************************************************************************/ +BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,strlen(fname)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBsetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0, attr); + put_dos_date3(cli->outbuf,smb_vwv1, t); + + p = smb_buf(cli->outbuf); + *p = 4; + strcpy(p+1, fname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } - st->st_mtime = make_unix_date3(cli->inbuf+smb_vwv1); return True; } -- cgit From c16d132bf95d96e2aa572cb9ba18a68abfbbeb8d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 05:55:44 +0000 Subject: added some QPATHINFO and QFILEINFO tests into smbtorture. This tests for things like midnight access times, sticky create times and word reversed INFO_STANDARD returns (This used to be commit 89141de14edf9e46ab279d2a74a9b026716a0ba8) --- source3/libsmb/clientgen.c | 116 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 39d1226f9d..7060467aee 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -24,6 +24,7 @@ #endif #include "includes.h" +#include "trans2.h" extern int DEBUGLEVEL; @@ -57,8 +58,8 @@ static BOOL cli_send_trans(struct cli_state *cli, char *outdata,*outparam; char *p; - this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */ - this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*SIZEOFWORD+this_lparam)); + this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ + this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); bzero(cli->outbuf,smb_size); set_message(cli->outbuf,14+lsetup,0,True); @@ -83,7 +84,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ for (i=0;ioutbuf,smb_setup+i*SIZEOFWORD,setup[i]); + SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); if (trans==SMBtrans) { strcpy(p,name); /* name[] */ @@ -131,7 +132,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ if (trans==SMBtrans2) - SSVAL(cli->outbuf,smb_sfid,fid); /* fid */ + SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ if (this_lparam) /* param[] */ memcpy(outparam,param,this_lparam); if (this_ldata) /* data[] */ @@ -243,7 +244,7 @@ static BOOL cli_api(struct cli_state *cli, int *rdrcnt, char *param,char *data, char **rparam, char **rdata) { - cli_send_trans(cli,SMBtrans,"\\PIPE\\LANMAN",0,0, + cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, data,param,NULL, drcnt,prcnt,0, mdrcnt,mprcnt,0); @@ -942,6 +943,111 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) return True; } +/**************************************************************************** +send a qpathinfo call +****************************************************************************/ +BOOL cli_qpathinfo(struct cli_state *cli, char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = strlen(fname) + 7; + + memset(param, 0, param_len); + SSVAL(param, 0, SMB_INFO_STANDARD); + pstrcpy(¶m[6], fname); + + if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, + NULL, param, &setup, + data_len, param_len, 1, + cli->max_xmit, 10, 0)) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, + &rdata, &rparam)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = make_unix_date2(rdata+0); + } + if (a_time) { + *a_time = make_unix_date2(rdata+4); + } + if (m_time) { + *m_time = make_unix_date2(rdata+8); + } + if (size) { + *size = IVAL(rdata, 12); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + + +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = 4; + + memset(param, 0, param_len); + SSVAL(param, 0, fnum); + SSVAL(param, 2, SMB_INFO_STANDARD); + + if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, + NULL, param, &setup, + data_len, param_len, 1, + cli->max_xmit, 2, 0)) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, + &rdata, &rparam)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = make_unix_date2(rdata+0); + } + if (a_time) { + *a_time = make_unix_date2(rdata+4); + } + if (m_time) { + *m_time = make_unix_date2(rdata+8); + } + if (size) { + *size = IVAL(rdata, 12); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + /**************************************************************************** send a negprot command -- cgit From 931d0150b0751d2e52cded550061374826214943 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 07:26:42 +0000 Subject: added a SMB_QUERY_FILE_ALL_INFO test into smbtorture W95 doesn't seem to support this call. (This used to be commit 162947c6e672580216c6223a44d25b874f0487ab) --- source3/libsmb/clientgen.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7060467aee..89557905fc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -995,6 +995,62 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, return True; } +/**************************************************************************** +send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level +****************************************************************************/ +BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, uint32 *size) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = strlen(fname) + 7; + + memset(param, 0, param_len); + SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); + pstrcpy(¶m[6], fname); + + if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, + NULL, param, &setup, + data_len, param_len, 1, + cli->max_xmit, 10, 0)) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, + &rdata, &rparam)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = interpret_long_date(rdata+0) - cli->serverzone; + } + if (a_time) { + *a_time = interpret_long_date(rdata+8) - cli->serverzone; + } + if (m_time) { + *m_time = interpret_long_date(rdata+16) - cli->serverzone; + } + if (w_time) { + *w_time = interpret_long_date(rdata+24) - cli->serverzone; + } + if (size) { + *size = IVAL(rdata, 40); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + /**************************************************************************** send a qfileinfo call -- cgit From ebe7c7a173efa32057908af43a5c3d74d8b3739a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Nov 1997 13:44:52 +0000 Subject: added cli_rmdir and cli_mkdir added test in smbtorture for the server updating the directory modify time when a file is added to a directory cleanup in smbtorture so no garbage files are left on the server (This used to be commit 3a5e07f1e994396853e6340e8ef3f4d12bb0243e) --- source3/libsmb/clientgen.c | 66 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 89557905fc..1bd55cffe8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -594,7 +594,71 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; strcpy(p,fname); - p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** +create a directory +****************************************************************************/ +BOOL cli_mkdir(struct cli_state *cli, char *dname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0, 2 + strlen(dname),True); + + CVAL(cli->outbuf,smb_com) = SMBmkdir; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,dname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** +remove a directory +****************************************************************************/ +BOOL cli_rmdir(struct cli_state *cli, char *dname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0, 2 + strlen(dname),True); + + CVAL(cli->outbuf,smb_com) = SMBrmdir; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,dname); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { -- cgit From 15a6097263d4d5179b0eed43ede74fd65a83e090 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 30 Nov 1997 02:58:34 +0000 Subject: clientgen.c: Added cli_mv() (used in a recent torture test). reply.c: Changed reply_open_and_X to split out the oplock request bits from core and extended and if an oplock was granted only set the corresponding bit on reply. server.c: Added code to dynamically allocate i/o buffers in oplock_break (prevents recursion problems) , also made reset of sent_oplock_break explicit. Jeremy. (This used to be commit 16e55ee2b8be9a4210d8cf87691cdf42373759d2) --- source3/libsmb/clientgen.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1bd55cffe8..69e940845c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -573,6 +573,43 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +/**************************************************************************** +rename a file +****************************************************************************/ +BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); + + CVAL(cli->outbuf,smb_com) = SMBmv; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,fname_src); + p = skip_string(p,1); + *p++ = 4; + strcpy(p,fname_dst); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + /**************************************************************************** delete a file ****************************************************************************/ -- cgit From f97a49c39e467b1efb93fc3b585af92c3e52f606 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 1997 23:30:43 +0000 Subject: add the null string to SMBsetatr calls (This used to be commit fbb2be050ded099741345a101ba13e6b12ebc823) --- source3/libsmb/clientgen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 69e940845c..d827eadfe1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1019,7 +1019,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - set_message(cli->outbuf,8,strlen(fname)+2,True); + set_message(cli->outbuf,8,strlen(fname)+4,True); CVAL(cli->outbuf,smb_com) = SMBsetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1031,6 +1031,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; strcpy(p+1, fname); + p = skip_string(p,1); + *p = 4; send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { -- cgit From be71d43585cf4b42efff7995dbf061fddd6077f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 20 Dec 1997 14:36:11 +0000 Subject: client.c: clientgen.c: clientutil.c: clitar.c: Changed usage of receive_smb to new function client_receive_smb except for one use of receive_smb in client.c. This is the receive_smb used to discard packets received whilst in a keyboard wait state. util.c: Created new function client_receive_smb that ignores session keepalives just as the old receive_smb used to do. Created internal function read_smb_length_return_keepalive that is used internally by the changed receive_smb call. Changed read_smb_len to not use an internal buffer - it is never called with a null buffer so such code is redundant. Jeremy. (This used to be commit 1084fb46821cb96702da35439da4a8df9d255698) --- source3/libsmb/clientgen.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d827eadfe1..4185c19fea 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,7 @@ static BOOL cli_send_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout) || CVAL(cli->inbuf,smb_rcls) != 0) { return(False); } @@ -165,7 +165,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, *data_len = *param_len = 0; - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -216,7 +216,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, if (total_data <= *data_len && total_param <= *param_len) break; - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -484,7 +484,7 @@ BOOL cli_session_setup(struct cli_state *cli, } send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -543,7 +543,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; if (CVAL(cli->inbuf,smb_rcls) != 0) { @@ -567,7 +567,7 @@ BOOL cli_tdis(struct cli_state *cli) cli_setup_packet(cli); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; return CVAL(cli->inbuf,smb_rcls) == 0; @@ -599,7 +599,7 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) strcpy(p,fname_dst); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -633,7 +633,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) strcpy(p,fname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -666,7 +666,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) strcpy(p,dname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -698,7 +698,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) strcpy(p,dname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -758,7 +758,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = skip_string(p,1); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -790,7 +790,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SIVALS(cli->outbuf,smb_vwv1,-1); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -831,7 +831,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SIVAL(p, 6, len); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -871,7 +871,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 6, len); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -906,7 +906,7 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s SSVAL(cli->outbuf,smb_vwv6,size); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -950,7 +950,7 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 memcpy(p, buf, size); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -984,7 +984,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, strcpy(p+1, fname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1035,7 +1035,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) *p = 4; send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1242,7 +1242,7 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -1322,7 +1322,7 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, send_smb(cli->fd,cli->outbuf); DEBUG(5,("Sent session request\n")); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; if (CVAL(cli->inbuf,0) != 0x82) { -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4185c19fea..319a77beb6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client generic functions - Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Andrew Tridgell 1994-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 -- cgit From c54af0f8b20e3f93c59da6a817920e1de6c4a870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 16 Mar 1998 20:59:47 +0000 Subject: Adding the same change as was added to 1.9.18 branch to add the "name resolve order" parameter. source/Makefile: Re-ordered link for name resolve order code. source/clientgen.c: source/clientutil.c: Added calls to resolve_name(). source/includes.h: Added HPUX zombie fix. source/loadparm.c: Added new name resolve order parameter. source/namequery.c: Re-wrote to include parsing of lmhosts file, new resolve_name() function requested by John. source/nmbd.c: Tell resolve_name not to do WINS lookups if we are the WINS server. source/nmbd_lmhosts.c: Call lmhosts parsing functions in namequery.c source/password.c: Call resolve_name() to lookup security=server name. source/reply.c: source/time.c: source/trans2.c: "fake directory create times" fix from Jim Hague - hague@research.canon.com.au. source/util.c: Removed isalnum() test in Get_Hostname() that seems to cause problems on many systems. Jeremy. (This used to be commit 7f118970da7c43eaddcf92dc056d3e849f1e7d5c) --- source3/libsmb/clientgen.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 319a77beb6..4585c8a544 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1343,13 +1343,9 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip) { - struct hostent *hp; - - if ((hp = Get_Hostbyname(cli->desthost)) == 0) { - return False; - } - - putip((char *)&dest_ip,(char *)hp->h_addr); + if(!resolve_name( cli->desthost, &dest_ip)) { + return False; + } } else { dest_ip = *ip; } -- cgit From 7abbf368f908cacdb2978e33069e49755e54faa8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Mar 1998 20:06:47 +0000 Subject: Adding the same changes to HEAD as were added to BRANCH_1_9_18. Changed smbpasswd to be client-server for a normal user, rather than accessing the private/smbpasswd file directly (it still accesses this file directly when run as root, so root can add users/change a users password without knowing the old password). A shakeout of this change is that smbpasswd can now be used to change a users password on a remote NT machine (yep - you heard that one right - we can now change a NT password from UNIX !!!!!). Jeremy. (This used to be commit 20770b6f1c25288e90d3e0d215afa7f0809ce124) --- source3/libsmb/clientgen.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4585c8a544..dcebf70455 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -426,7 +426,7 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & 2) && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); } else { @@ -1207,6 +1207,104 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return True; } +/**************************************************************************** +Send a SamOEMChangePassword command +****************************************************************************/ + +BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password, + char *old_password) +{ + char param[16+sizeof(fstring)]; + char data[532]; + char *p = param; + fstring upper_case_old_pw; + fstring upper_case_new_pw; + unsigned char old_pw_hash[16]; + unsigned char new_pw_hash[16]; + int data_len; + int param_len = 0; + int new_pw_len = strlen(new_password); + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + + cli->error = -1; + + if(strlen(user) >= sizeof(fstring)-1) { + DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); + return False; + } + + if(new_pw_len > 512) { + DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user)); + return False; + } + + SSVAL(p,0,214); /* SamOEMChangePassword command. */ + p += 2; + strcpy(p, "zsT"); + p = skip_string(p,1); + strcpy(p, "B516B16"); + p = skip_string(p,1); + fstrcpy(p,user); + p = skip_string(p,1); + SSVAL(p,0,532); + p += 2; + + param_len = PTR_DIFF(p,param); + + /* + * Now setup the data area. + */ + memset(data, '\0', sizeof(data)); + fstrcpy( &data[512 - new_pw_len], new_password); + SIVAL(data, 512, new_pw_len); + + /* + * Get the Lanman hash of the old password, we + * use this as the key to SamOEMHash(). + */ + memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); + fstrcpy(upper_case_old_pw, old_password); + strupper(upper_case_old_pw); + E_P16((uchar *)upper_case_old_pw, old_pw_hash); + + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + + /* + * Now place the old password hash in the data. + */ + memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); + fstrcpy(upper_case_new_pw, new_password); + strupper(upper_case_new_pw); + + E_P16((uchar *)upper_case_new_pw, new_pw_hash); + + E_old_pw_hash( new_pw_hash, old_pw_hash, &data[516]); + + data_len = 532; + + if(cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, + data,param,NULL, + data_len , param_len,0, + 0,2,0) == False) { + DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", + user )); + return False; + } + + if(cli_receive_trans(cli,SMBtrans, &rdrcnt, &rprcnt, &rdata, &rparam)) { + if(rparam) + cli->error = SVAL(rparam,0); + } + + if (rparam) + free(rparam); + if (rdata) + free(rdata); + + return (cli->error == 0); +} /**************************************************************************** send a negprot command -- cgit From 5d7c8375e4ffb017ef0f9eed7e619e533b3e8d12 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Mar 1998 00:37:53 +0000 Subject: clientgen.c ipc.c smbpasswd.c: Fixes for warnings (from Herb). quotas.c: Linux quota fix. util.c: Ensure smb_read_error is zero in all calls that can set it. lib/rpc/include/rpc_misc.h lib/rpc/include/rpc_netlogon.h lib/rpc/parse/parse_misc.c lib/rpc/parse/parse_net.c lib/rpc/server/srv_netlog.c : Modify Luke's code to call SamOEMhash(). Jeremy. (This used to be commit 7f749708383b8b36c3f23a5fbc5cbdf39bc8e555) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index dcebf70455..4f57c08a95 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1280,7 +1280,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo E_P16((uchar *)upper_case_new_pw, new_pw_hash); - E_old_pw_hash( new_pw_hash, old_pw_hash, &data[516]); + E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); data_len = 532; -- cgit From 5f7e1d2aa5ad4c57074c9344f7a970e8bd783dda Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Apr 1998 02:48:52 +0000 Subject: support O_SYNC in opens for smbtorture (This used to be commit 000b871839e12065fc514f857ba205590a95b040) --- source3/libsmb/clientgen.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4f57c08a95..4bca10cb3a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -737,6 +737,10 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) accessmode |= 1; } + if ((flags & O_SYNC) == O_SYNC) { + accessmode |= (1<<14); + } + bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); -- cgit From f9a96f060bdc8d045748b5f7e31d177e43e8810a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Apr 1998 22:44:01 +0000 Subject: clientgen.c: Changes 'cli_xxx_' calls to use the following regularized parameter syntax: setup, setup_count, max_setup_count, params, params_count, max_params_count, data, data_count, max_data_count, (and if a reply is needed) *reply_params, *reply_data_len *reply_data, *reply_data_len This allows the pointers and the lengths that relate to these pointers to be next to each other in the parameter list. This makes seeing what you are passing to these functions much easier to see. Getting ready for adding the lib/rpc/client functions needed to do security=domain. torture.c: Fixed it so it uses / rather than \\ internally for the //machine/share syntax. Jeremy. (This used to be commit 38350ea8b949d0908497490898ff04df7591ccac) --- source3/libsmb/clientgen.c | 152 +++++++++++++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 53 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4bca10cb3a..bffce26294 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -47,10 +47,12 @@ static void cli_setup_packet(struct cli_state *cli) /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, - int trans, char *name, int fid, int flags, - char *data,char *param,uint16 *setup, int ldata,int lparam, - int lsetup,int mdata,int mparam,int msetup) +static BOOL cli_send_trans(struct cli_state *cli, int trans, + char *name, int pipe_name_len, + int fid, int flags, + uint16 *setup, int lsetup, int msetup, + char *param, int lparam, int mparam, + char *data, int ldata, int mdata) { int i; int this_ldata,this_lparam; @@ -67,7 +69,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3); + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); outdata = outparam+this_lparam; /* primary request */ @@ -87,7 +89,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); if (trans==SMBtrans) { - strcpy(p,name); /* name[] */ + memcpy(p,name, pipe_name_len + 1); /* name[] */ } else { *p++ = 0; /* put in a null smb_name */ *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ @@ -155,9 +157,9 @@ static BOOL cli_send_trans(struct cli_state *cli, /**************************************************************************** receive a SMB trans or trans2 response allocating the necessary memory ****************************************************************************/ -static BOOL cli_receive_trans(struct cli_state *cli, - int trans,int *data_len, - int *param_len, char **data,char **param) +static BOOL cli_receive_trans(struct cli_state *cli,int trans, + char **param, int *param_len, + char **data, int *data_len) { int total_data=0; int total_param=0; @@ -235,23 +237,51 @@ static BOOL cli_receive_trans(struct cli_state *cli, return(True); } +/**************************************************************************** +Call a remote api on an arbitrary pipe. takes param, data and setup buffers. +****************************************************************************/ +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count) +{ + if(pipe_name_len == 0) + pipe_name_len = strlen(pipe_name); + + cli_send_trans(cli, SMBtrans, + pipe_name, pipe_name_len, + 0,0, /* fid, flags */ + setup, setup_count, max_setup_count, + params, param_count, max_param_count, + data, data_count, max_data_count); + + return (cli_receive_trans(cli, SMBtrans, + rparam, rparam_count, + rdata, rdata_count)); +} /**************************************************************************** call a remote api ****************************************************************************/ static BOOL cli_api(struct cli_state *cli, - int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, - int *rdrcnt, char *param,char *data, - char **rparam, char **rdata) + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt) { - cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, - data,param,NULL, - drcnt,prcnt,0, - mdrcnt,mprcnt,0); + cli_send_trans(cli,SMBtrans, + PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ + 0,0, /* fid, flags */ + NULL,0,0, /* Setup, length, max */ + param, prcnt, mprcnt, /* Params, length, max */ + data, drcnt, mdrcnt /* Data, length, max */ + ); return (cli_receive_trans(cli,SMBtrans, - rdrcnt,rprcnt, - rdata,rparam)); + rparam, rprcnt, + rdata, rdrcnt)); } @@ -291,11 +321,12 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) cli->error = -1; - if (cli_api(cli, PTR_DIFF(p,param),0, - 1024,BUFFER_SIZE, - &rprcnt,&rdrcnt, - param,NULL, - &rparam,&rdata)) { + if (cli_api(cli, + param, PTR_DIFF(p,param),1024, /* param, length, max */ + NULL, 0, BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { cli->error = SVAL(rparam,0); p = rdata; @@ -352,13 +383,11 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = skip_string(p,1); if (cli_api(cli, - PTR_DIFF(p,param), /* param count */ - 0, /*data count */ - 8, /* mprcount */ - BUFFER_SIZE, /* mdrcount */ - &rprcnt,&rdrcnt, - param, NULL, - &rparam,&rdata)) { + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { int res = SVAL(rparam,0); int converter=SVAL(rparam,2); int i; @@ -1068,15 +1097,19 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); - if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, - NULL, param, &setup, - data_len, param_len, 1, - cli->max_xmit, 10, 0)) { + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { return False; } - if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, - &rdata, &rparam)) { + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { return False; } @@ -1121,15 +1154,19 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); pstrcpy(¶m[6], fname); - if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, - NULL, param, &setup, - data_len, param_len, 1, - cli->max_xmit, 10, 0)) { + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { return False; } - if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, - &rdata, &rparam)) { + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { return False; } @@ -1177,15 +1214,19 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_INFO_STANDARD); - if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, - NULL, param, &setup, - data_len, param_len, 1, - cli->max_xmit, 2, 0)) { + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { return False; } - if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, - &rdata, &rparam)) { + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { return False; } @@ -1288,16 +1329,21 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo data_len = 532; - if(cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, - data,param,NULL, - data_len , param_len,0, - 0,2,0) == False) { + if(cli_send_trans(cli,SMBtrans, + PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ + 0,0, /* fid, flags */ + NULL,0,0, /* setup, length, max */ + param,param_len,2, /* param, length, max */ + data,data_len,0 /* data, length, max */ + ) == False) { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; } - if(cli_receive_trans(cli,SMBtrans, &rdrcnt, &rprcnt, &rdata, &rparam)) { + if(cli_receive_trans(cli,SMBtrans, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { if(rparam) cli->error = SVAL(rparam,0); } -- cgit From efb71742ca8ff9ec3211c5b3cf5d311fdceecd1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Apr 1998 22:43:54 +0000 Subject: Makefile: Added genrand.o clientgen.c: Changed to fill change password buffer with random stuff. password.c: Changed to get challenge from genrand.c server.c: Added #ifdef around O_SYNC. version.h: Changed to 1.9.19prealpha. genrand.c: New code to generate (hopefully) good random numbers for use in crypto challenges/session keys etc. PLEASE REVIEW THIS CODE AND SUGGEST IMPROVEMENTS !!!!!! Jeremy. (This used to be commit 608e98546392fd0aac9b33f4feac43615dbb4405) --- source3/libsmb/clientgen.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bffce26294..1f2f746576 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -766,9 +766,11 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) accessmode |= 1; } +#if defined(O_SYNC) if ((flags & O_SYNC) == O_SYNC) { accessmode |= (1<<14); } +#endif /* O_SYNC */ bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); @@ -1300,8 +1302,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo /* * Now setup the data area. + * We need to generate a random fill + * for this area to make it harder to + * decrypt. JRA. */ - memset(data, '\0', sizeof(data)); + generate_random_buffer(data, sizeof(data), False); fstrcpy( &data[512 - new_pw_len], new_password); SIVAL(data, 512, new_pw_len); -- cgit From 2dee1ed38867504d067d593c62734ecff0eca77c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Apr 1998 02:23:24 +0000 Subject: clientgen.c: Added cli_ulogoff() call. password.c: Added call to cli_ulogoff on successfull sessionsetup. Jeremy. (This used to be commit 77882f002b2a8203aad419e485fc885303d999a0) --- source3/libsmb/clientgen.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1f2f746576..ea51395a8f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -528,6 +528,25 @@ BOOL cli_session_setup(struct cli_state *cli, return True; } +/**************************************************************************** + Send a uloggoff. +*****************************************************************************/ + +BOOL cli_ulogoff(struct cli_state *cli) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,2,0,True); + CVAL(cli->outbuf,smb_com) = SMBulogoffX; + cli_setup_packet(cli); + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + return CVAL(cli->inbuf,smb_rcls) == 0; +} /**************************************************************************** send a tconX -- cgit From 002a47de8e0cf03c79cedbed2db52f391001f459 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 20:12:17 +0000 Subject: clientgen.c: Added rap error codes to cli_error, moved from smbpasswd.c password.c: Changed global cli -> pw_cli, removed strtok (bad strtok, bad :-) use in security=server, started to extend security=domain code. smbpasswd.c: Removed rap error code functions. Jeremy. (This used to be commit 0f00b8fce1a5cad7f8c212568fa33f09986e5bd6) --- source3/libsmb/clientgen.c | 71 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ea51395a8f..9de6afccee 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -29,6 +29,69 @@ extern int DEBUGLEVEL; +/***************************************************** + RAP error codes - a small start but will be extended. +*******************************************************/ + +struct +{ + int err; + char *message; +} rap_errmap[] = +{ + {5, "User has insufficient privilege" }, + {86, "The specified password is invalid" }, + {2226, "Operation only permitted on a Primary Domain Controller" }, + {2242, "The password of this user has expired." }, + {2243, "The password of this user cannot change." }, + {2244, "This password cannot be used now (password history conflict)." }, + {2245, "The password is shorter than required." }, + {2246, "The password of this user is too recent to change."}, + {0, NULL} +}; + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +char *cli_smb_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) +{ + static fstring error_message; + int errclass; + int errnum; + int i; + + /* + * Errors are of two kinds - smb errors, + * dealt with by cli_smb_errstr, and rap + * errors, whose error code is in cli.error. + */ + + cli_error(cli, &errclass, &errnum); + if(errclass != 0) + return cli_smb_errstr(cli); + + sprintf(error_message, "code %d", cli->error); + + for(i = 0; rap_errmap[i].message != NULL; i++) { + if (rap_errmap[i].err == cli->error) { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + + return error_message; +} + /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ @@ -1566,14 +1629,6 @@ void cli_shutdown(struct cli_state *cli) memset(cli, 0, sizeof(*cli)); } -/**************************************************************************** - return a description of the error -****************************************************************************/ -char *cli_errstr(struct cli_state *cli) -{ - return smb_errstr(cli->inbuf); -} - /**************************************************************************** return error codes for the last packet ****************************************************************************/ -- cgit From 30675f81f60bab24f47758baab8316d4467709ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 22:59:19 +0000 Subject: Makefile: Added nterr.c into the mix. clientgen.c: Added nt_error as an entry in the struct client_state. password.c: Open the netlogon pipe. smb.h: Added nt_error as an entry in the struct client_state. lib/rpc/parse/parse_net.c: Added comments on net logon. lib/rpc/server/srv_netlog.c: Added comments on net logon. Jeremy. (This used to be commit 899a9f0dce50c73e03c8da2ebe920957491c8ad7) --- source3/libsmb/clientgen.c | 53 +++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9de6afccee..f23c846cf9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -71,19 +71,39 @@ char *cli_errstr(struct cli_state *cli) int i; /* - * Errors are of two kinds - smb errors, - * dealt with by cli_smb_errstr, and rap - * errors, whose error code is in cli.error. + * Errors are of three kinds - smb errors, + * dealt with by cli_smb_errstr, NT errors, + * whose code is in cli.nt_error, and rap + * errors, whose error code is in cli.rap_error. */ cli_error(cli, &errclass, &errnum); if(errclass != 0) return cli_smb_errstr(cli); - - sprintf(error_message, "code %d", cli->error); + + /* + * Was it an NT error ? + */ + + if(cli->nt_error) { + char *nt_msg = get_nt_error_msg(cli->nt_error); + + if(nt_msg == NULL) + sprintf(error_message, "NT code %d", cli->nt_error); + else + fstrcpy(error_message, nt_msg); + + return error_message; + } + + /* + * Must have been a rap error. + */ + + sprintf(error_message, "code %d", cli->rap_error); for(i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->error) { + if (rap_errmap[i].err == cli->rap_error) { fstrcpy( error_message, rap_errmap[i].message); break; } @@ -97,6 +117,8 @@ setup basics in a outgoing packet ****************************************************************************/ static void cli_setup_packet(struct cli_state *cli) { + cli->rap_error = 0; + cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->uid); SSVAL(cli->outbuf,smb_mid,cli->mid); @@ -382,29 +404,27 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) SSVAL(p, 0, BUFFER_SIZE); p += 2; - cli->error = -1; - if (cli_api(cli, param, PTR_DIFF(p,param),1024, /* param, length, max */ NULL, 0, BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { - cli->error = SVAL(rparam,0); + cli->rap_error = SVAL(rparam,0); p = rdata; - if (cli->error == 0) { + if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); cli->privilages = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { - DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); + DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); } } if (rparam) free(rparam); if (rdata) free(rdata); - return cli->error == 0; + return (cli->rap_error == 0); } @@ -1357,8 +1377,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo char *rdata = NULL; int rprcnt, rdrcnt; - cli->error = -1; - if(strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); return False; @@ -1432,7 +1450,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo &rparam, &rprcnt, &rdata, &rdrcnt)) { if(rparam) - cli->error = SVAL(rparam,0); + cli->rap_error = SVAL(rparam,0); } if (rparam) @@ -1440,7 +1458,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo if (rdata) free(rdata); - return (cli->error == 0); + return (cli->rap_error == 0); } /**************************************************************************** @@ -1561,7 +1579,8 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, return False; if (CVAL(cli->inbuf,0) != 0x82) { - cli->error = CVAL(cli->inbuf,0); + /* This is the wrong place to put the error... JRA. */ + cli->rap_error = CVAL(cli->inbuf,0); return False; } return(True); -- cgit From d7cecb7bd3cfcab48af07366e24b65b2bb8b09bb Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 28 Apr 1998 09:53:42 +0000 Subject: added NetShareEnum from Bartlomej Czardybon (This used to be commit 37cbc356741055d0660b80594117fa312d252b85) --- source3/libsmb/clientgen.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f23c846cf9..3f8c6e32cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -427,6 +427,65 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } +/**************************************************************************** +call a NetShareEnum - try and browse available connections on a host +****************************************************************************/ +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *)) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + pstring param; + int count = -1; + + /* now send a SMBtrans command with api RNetShareEnum */ + p = param; + SSVAL(p,0,0); /* api number */ + p += 2; + strcpy(p,"WrLeh"); + p = skip_string(p,1); + strcpy(p,"B13BWz"); + p = skip_string(p,1); + SSVAL(p,0,1); + SSVAL(p,2,BUFFER_SIZE); + p += 4; + + if (cli_api(cli, + PTR_DIFF(p,param), + 0, /* data count */ + 1024, /* mprcount */ + BUFFER_SIZE, /* mdrcount */ + &rprcnt, &rdrcnt, + param,NULL, + &rparam,&rdata)) + { + int res = SVAL(rparam,0); + int converter=SVAL(rparam,2); + int i; + BOOL long_share_name=False; + + if (res == 0) + { + count=SVAL(rparam,4); + p = rdata; + + for (i=0;i0); +} /**************************************************************************** call a NetServerEnum for the specified workgroup and servertype mask. -- cgit From b807469d40a816e9f61b797b6ab26a40bb4363cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Apr 1998 16:43:02 +0000 Subject: Fixed checked in code that didn't compile. Jeremy. (This used to be commit 5f258abf526243f753c3a64cde2e1f67e4d60b6b) --- source3/libsmb/clientgen.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3f8c6e32cc..7fc19a5f39 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -452,18 +452,14 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) p += 4; if (cli_api(cli, - PTR_DIFF(p,param), - 0, /* data count */ - 1024, /* mprcount */ - BUFFER_SIZE, /* mdrcount */ - &rprcnt, &rdrcnt, - param,NULL, - &rparam,&rdata)) + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ { int res = SVAL(rparam,0); int converter=SVAL(rparam,2); int i; - BOOL long_share_name=False; if (res == 0) { @@ -1465,7 +1461,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo * for this area to make it harder to * decrypt. JRA. */ - generate_random_buffer(data, sizeof(data), False); + generate_random_buffer((unsigned char *)data, sizeof(data), False); fstrcpy( &data[512 - new_pw_len], new_password); SIVAL(data, 512, new_pw_len); -- cgit From e305c2c9e2e657974d34d1d58a8f9372921fdae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 19:22:01 +0000 Subject: clientgen.c: Fixed null session setup bug. password.c: Stopped cli_nt_logout call (we don't have it correct yet). Added Luke object-orientation fix :-). smb.h: Added clnt_name_slash to cli_state. lib/rpc/client/cli_login.c: Changed global_myname to clnt_name_slash where needed. lib/rpc/client/cli_netlogon.c: Fixed debug messages, don't check creds on error. lib/rpc/client/cli_pipe.c: Fixed debug messages, Added Luke object-orientation fix. lib/rpc/parse/parse_misc.c: Fixed STRING2 linearization bug that was adding 1. Jeremy. (This used to be commit c6c22df20196cb7f0ae84b1a1dd202a87adb8d4e) --- source3/libsmb/clientgen.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7fc19a5f39..d72040505f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -593,12 +593,17 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & 2) && passlen != 24) { - passlen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } else { - memcpy(pword, pass, passlen); - } + if(((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + /* Null session connect. */ + pword[0] = '\0'; + } else { + if ((cli->sec_mode & 2) && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + } /* if in share level security then don't send a password now */ if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/libsmb/clientgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d72040505f..8b4001827c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -343,8 +343,8 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, data, data_count, max_data_count); return (cli_receive_trans(cli, SMBtrans, - rparam, rparam_count, - rdata, rdata_count)); + rparam, (int *)rparam_count, + rdata, (int *)rdata_count)); } /**************************************************************************** @@ -714,7 +714,8 @@ BOOL cli_send_tconX(struct cli_state *cli, memcpy(pword, pass, passlen); } - sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/libsmb/clientgen.c | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8b4001827c..9dfd482da3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -89,7 +89,7 @@ char *cli_errstr(struct cli_state *cli) char *nt_msg = get_nt_error_msg(cli->nt_error); if(nt_msg == NULL) - sprintf(error_message, "NT code %d", cli->nt_error); + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); else fstrcpy(error_message, nt_msg); @@ -100,7 +100,7 @@ char *cli_errstr(struct cli_state *cli) * Must have been a rap error. */ - sprintf(error_message, "code %d", cli->rap_error); + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); for(i = 0; rap_errmap[i].message != NULL; i++) { if (rap_errmap[i].err == cli->rap_error) { @@ -387,16 +387,16 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p = param; SSVAL(p,0,132); /* api number */ p += 2; - strcpy(p,"OOWb54WrLh"); + pstrcpy(p,"OOWb54WrLh"); p = skip_string(p,1); - strcpy(p,"WB21BWDWWDDDDDDDzzzD"); + pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); p = skip_string(p,1); SSVAL(p,0,1); p += 2; - strcpy(p,user); + pstrcpy(p,user); strupper(p); p += 21; p++; p += 15; p++; - strcpy(p, workstation); + pstrcpy(p, workstation); strupper(p); p += 16; SSVAL(p, 0, BUFFER_SIZE); @@ -443,9 +443,9 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) p = param; SSVAL(p,0,0); /* api number */ p += 2; - strcpy(p,"WrLeh"); + pstrcpy(p,"WrLeh"); p = skip_string(p,1); - strcpy(p,"B13BWz"); + pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); SSVAL(p,2,BUFFER_SIZE); @@ -505,10 +505,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - strcpy(p,"WrLehDz"); + pstrcpy(p,"WrLehDz"); p = skip_string(p,1); - strcpy(p,"B16BBDz"); + pstrcpy(p,"B16BBDz"); p = skip_string(p,1); SSVAL(p,0,uLevel); @@ -625,7 +625,7 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,user); + pstrcpy(p,user); strupper(p); } else { set_message(cli->outbuf,13,0,True); @@ -644,14 +644,14 @@ BOOL cli_session_setup(struct cli_state *cli, p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpass,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - strcpy(p,user); + pstrcpy(p,user); strupper(p); p = skip_string(p,1); - strcpy(p,workgroup); + pstrcpy(p,workgroup); strupper(p); p = skip_string(p,1); - strcpy(p,"Unix");p = skip_string(p,1); - strcpy(p,"Samba");p = skip_string(p,1); + pstrcpy(p,"Unix");p = skip_string(p,1); + pstrcpy(p,"Samba");p = skip_string(p,1); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } @@ -728,9 +728,9 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,fullshare); + fstrcpy(p,fullshare); p = skip_string(p,1); - strcpy(p,dev); + pstrcpy(p,dev); SCVAL(cli->inbuf,smb_rcls, 1); @@ -785,10 +785,10 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,fname_src); + pstrcpy(p,fname_src); p = skip_string(p,1); *p++ = 4; - strcpy(p,fname_dst); + pstrcpy(p,fname_dst); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -822,7 +822,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,fname); + pstrcpy(p,fname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -855,7 +855,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,dname); + pstrcpy(p,dname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -887,7 +887,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,dname); + pstrcpy(p,dname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -952,7 +952,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); - strcpy(p,fname); + pstrcpy(p,fname); p = skip_string(p,1); send_smb(cli->fd,cli->outbuf); @@ -1179,7 +1179,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, p = smb_buf(cli->outbuf); *p = 4; - strcpy(p+1, fname); + pstrcpy(p+1, fname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -1228,7 +1228,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; - strcpy(p+1, fname); + pstrcpy(p+1, fname); p = skip_string(p,1); *p = 4; @@ -1450,11 +1450,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; - strcpy(p, "zsT"); + pstrcpy(p, "zsT"); p = skip_string(p,1); - strcpy(p, "B516B16"); + pstrcpy(p, "B516B16"); p = skip_string(p,1); - fstrcpy(p,user); + pstrcpy(p,user); p = skip_string(p,1); SSVAL(p,0,532); p += 2; @@ -1546,7 +1546,7 @@ BOOL cli_negprot(struct cli_state *cli) prots[numprots].name && prots[numprots].prot<=cli->protocol; numprots++) { *p++ = 2; - strcpy(p,prots[numprots].name); + pstrcpy(p,prots[numprots].name); p += strlen(p) + 1; } -- cgit From cb757820f5452d192ce3b1eeb4f19a17ee93c3fe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jun 1998 01:35:52 +0000 Subject: Added SSL support from Christian Starkjohann This patch may not yet compile with -DUSE_SSL enabled, further Makefile changes may be needed. But it was important to get this code in place before I go off to USENIX. Jeremy. (This used to be commit 31e768369fdc61e07c59630c86c62239f3d3f3f7) --- source3/libsmb/clientgen.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9dfd482da3..68bd369606 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1633,12 +1633,25 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, _smb_setlen(cli->outbuf,len); CVAL(cli->outbuf,0) = 0x81; +#ifdef USE_SSL +retry: +#endif /* USE_SSL */ + send_smb(cli->fd,cli->outbuf); DEBUG(5,("Sent session request\n")); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; +#ifdef USE_SSL + if(CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ + if(!sslutil_fd_is_ssl(cli->fd)){ + if(sslutil_connect(cli->fd) == 0) + goto retry; + } + } +#endif /* USE_SSL */ + if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,0); -- cgit From bbd7ca65e706457f5dbc046e83b4bd8cdde5be8f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jun 1998 18:25:36 +0000 Subject: clientgen: Added USE_SSL for client shutdown. clitar.c: Added 'Samba style' comments before string_create_s(). loadparm.c: Fixed missing comma in SSL code. util.c: Removed string_create_s(). Currently it's only called from clitar.c and having it here as well as a static in clitar causes the compile to break (Richard, please decide where you want this function). lib/rpc/parse/parse_net.c: Fix from to stop coredump on missing parameter. Jeremy. (This used to be commit d23b44322570cb9a7aa2b86407bf4f91010a237b) --- source3/libsmb/clientgen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 68bd369606..093b3aedf9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1718,6 +1718,9 @@ void cli_shutdown(struct cli_state *cli) { if (cli->outbuf) free(cli->outbuf); if (cli->inbuf) free(cli->inbuf); +#ifdef USE_SSL + if (cli->fd != -1) sslutil_disconnect(cli->fd); +#endif /* USE_SSL */ if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } -- cgit From 64578c0589a3a741f81fb55c16eeb882128da00b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 03:08:05 +0000 Subject: merge from the autoconf2 branch to the main branch (This used to be commit 3bda7ac417107a7b01d91805ca71c4330657ed21) --- source3/libsmb/clientgen.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 093b3aedf9..7dc57bfb47 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -19,9 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef SYSLOG -#undef SYSLOG -#endif +#define NO_SYSLOG #include "includes.h" #include "trans2.h" @@ -1633,9 +1631,9 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, _smb_setlen(cli->outbuf,len); CVAL(cli->outbuf,0) = 0x81; -#ifdef USE_SSL +#ifdef WITH_SSL retry: -#endif /* USE_SSL */ +#endif /* WITH_SSL */ send_smb(cli->fd,cli->outbuf); DEBUG(5,("Sent session request\n")); @@ -1643,14 +1641,14 @@ retry: if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; -#ifdef USE_SSL +#ifdef WITH_SSL if(CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ if(!sslutil_fd_is_ssl(cli->fd)){ if(sslutil_connect(cli->fd) == 0) goto retry; } } -#endif /* USE_SSL */ +#endif /* WITH_SSL */ if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ @@ -1718,9 +1716,9 @@ void cli_shutdown(struct cli_state *cli) { if (cli->outbuf) free(cli->outbuf); if (cli->inbuf) free(cli->inbuf); -#ifdef USE_SSL +#ifdef WITH_SSL if (cli->fd != -1) sslutil_disconnect(cli->fd); -#endif /* USE_SSL */ +#endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } -- cgit From 085c66aea549bcd89158336a8088c7563b7ebb36 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Aug 1998 06:42:09 +0000 Subject: some smbtorture hacks (random IPC calls) (This used to be commit b32a346a1c50ba40224b8165e08e78867be2d376) --- source3/libsmb/clientgen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7dc57bfb47..117d065f76 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -348,11 +348,11 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, /**************************************************************************** call a remote api ****************************************************************************/ -static BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt) { cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ -- cgit From 9076947b935fbeb13babf42974ff527ef916aabb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 07:21:54 +0000 Subject: if an address is ipzero in cli_connect() then do a name query (This used to be commit 0a5718b0aef29706be81a50f2ac2c5eb4c6fbb32) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 117d065f76..52919d9eb4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1665,10 +1665,11 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { struct in_addr dest_ip; + extern struct in_addr ipzero; fstrcpy(cli->desthost, host); - if (!ip) { + if (!ip || ip_equal(*ip, ipzero)) { if(!resolve_name( cli->desthost, &dest_ip)) { return False; } -- cgit From e9ea36e4d2270bd7d32da12ef6d6e2299641582d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 05:07:05 +0000 Subject: tridge the destroyer returns! prompted by the interpret_security() dead code that Jean-Francois pointed out I added a make target "finddead" that finds potentially dead (ie. unused) code. It spat out 304 function names ... I went through these are deleted many of them, making others static (finddead also reports functions that are used only in the local file). in doing this I have almost certainly deleted some useful code. I may have even prevented compilation with some compile options. I apologise. I decided it was better to get rid of this code now and add back the one or two functions that are needed than to keep all this baggage. So, if I have done a bit too much "destroying" then let me know. Keep the swearing to a minimum :) One bit I didn't do is the ubibt code. Chris, can you look at that? Heaps of unused functions there. Can they be made static? (This used to be commit 2204475c87f3024ea8fd1fbd7385b2def617a46f) --- source3/libsmb/clientgen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 52919d9eb4..c85de92989 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -51,7 +51,7 @@ struct /**************************************************************************** return a description of an SMB error ****************************************************************************/ -char *cli_smb_errstr(struct cli_state *cli) +static char *cli_smb_errstr(struct cli_state *cli) { return smb_errstr(cli->inbuf); } @@ -425,6 +425,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } +#if UNUSED_CODE /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ @@ -480,6 +481,7 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) return(count>0); } +#endif /**************************************************************************** call a NetServerEnum for the specified workgroup and servertype mask. @@ -763,6 +765,7 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +#if UNUSED_CODE /**************************************************************************** rename a file ****************************************************************************/ @@ -799,6 +802,7 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) return True; } +#endif /**************************************************************************** delete a file -- cgit From 66d5d73a5d75e88a77970f7b27687b8354ab2e80 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 25 Sep 1998 21:01:52 +0000 Subject: added rpcclient program (This used to be commit aa38f39d67fade4dfd7badb7a9b39c833a1dd1ca) --- source3/libsmb/clientgen.c | 173 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 161 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c85de92989..89caad419f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1604,31 +1604,26 @@ BOOL cli_negprot(struct cli_state *cli) /**************************************************************************** - send a session request + send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname) +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called) { - fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - fstrcpy(dest,host); + memcpy(&(cli->calling), calling, sizeof(*calling)); + memcpy(&(cli->called ), called , sizeof(*called )); - p = strchr(dest,'.'); - if (p) *p = 0; - - fstrcpy(cli->desthost, dest); - /* put in the destination name */ p = cli->outbuf+len; - name_mangle(dest,p,name_type); + name_mangle(cli->called .name, p, cli->called .name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(myname,p,0); + name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); /* setup the packet length */ @@ -1754,3 +1749,157 @@ int cli_setpid(struct cli_state *cli, int pid) cli->pid = pid; return ret; } + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_reestablish_connection(struct cli_state *cli) +{ + struct nmb_name calling; + struct nmb_name called; + fstring dest_host; + struct in_addr dest_ip; + fstring share; + fstring dev; + BOOL do_tcon = False; + + if (!cli->initialised || cli->fd == -1) + { + DEBUG(3,("cli_reestablish_connection: not connected\n")); + return False; + } + + /* copy the parameters necessary to re-establish the connection */ + + if (cli->cnum != 0) + { + fstrcpy(share, cli->share); + fstrcpy(dev , cli->dev); + do_tcon = True; + } + + memcpy(&called , &(cli->called ), sizeof(called )); + memcpy(&calling, &(cli->calling), sizeof(calling)); + fstrcpy(dest_host, cli->full_dest_host_name); + dest_ip = cli->dest_ip; + + DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", + namestr(&calling), namestr(&called), inet_ntoa(dest_ip), + cli->user_name, cli->domain)); + + return cli_establish_connection(cli, + dest_host, &dest_ip, + &calling, &called, + share, dev, False, do_tcon); +} + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon) +{ + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + namestr(calling), namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); + + /* establish connection */ + + if ((!cli->initialised)) + { + return False; + } + + if (cli->fd == -1) + { + if (!cli_connect(cli, dest_host, dest_ip)) + { + DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + namestr(calling), inet_ntoa(*dest_ip))); + return False; + } + } + + if (!cli_session_request(cli, calling, called)) + { + DEBUG(1,("failed session request\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (!cli_negprot(cli)) + { + DEBUG(1,("failed negprot\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (cli->pwd.cleartext || cli->pwd.null_pwd) + { + /* attempt clear-text session */ + + fstring passwd; + + pwd_get_cleartext(&(cli->pwd), passwd); + + /* attempt clear-text session */ + if (!cli_session_setup(cli, cli->user_name, + passwd, strlen(passwd), + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)passwd, strlen(passwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + else + { + /* attempt encrypted session */ + uchar nt_sess_pwd[24]; + uchar lm_sess_pwd[24]; + + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + + /* attempt encrypted session */ + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + + if (do_shutdown) cli_shutdown(cli); + + return True; +} -- cgit From cf3a9741dc7427efb97eff09a3c197a906ce6767 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Sep 1998 21:43:48 +0000 Subject: Changes to test in configure if capabilities are enabled on a system. Changes to get Samba to compile cleanly with the IRIX compiler with the options : -fullwarn -woff 1209,1174 (the -woff options are to turn off warnings about unused function parameters and controlling loop expressions being constants). Split prototype generation as we hit a limit in IRIX nawk. Removed "." code in smbd/filename.c (yet again :-). Jeremy. (This used to be commit e0567433bd72aec17bf5a54cc292701095d25f09) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 89caad419f..30f7dc5d99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1879,7 +1879,7 @@ BOOL cli_establish_connection(struct cli_state *cli, /* attempt encrypted session */ if (!cli_session_setup(cli, cli->user_name, (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - nt_sess_pwd, sizeof(nt_sess_pwd), + (char*)nt_sess_pwd, sizeof(nt_sess_pwd), cli->domain)) { DEBUG(1,("failed session setup\n")); -- cgit From 6ecd472ef3a8beaa78edfb7cc431fa07674c494f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Sep 1998 17:48:44 +0000 Subject: uchar / char typecast issues (This used to be commit 1a1d8d0483fc05765e6dcc2da00405e0ec7421a2) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 30f7dc5d99..214f6c4445 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1869,8 +1869,8 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ - uchar nt_sess_pwd[24]; - uchar lm_sess_pwd[24]; + char nt_sess_pwd[24]; + char lm_sess_pwd[24]; /* creates (storing a copy of) and then obtains a 24 byte password OWF */ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); -- cgit From 9066025a8a4afe1f7f559c455d86fc023792ed17 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Sep 1998 20:24:17 +0000 Subject: Got very strict about the differences and uses of uid_t, gid_t and vuid. Added sys_getgroups() to get around the int * return problem. Set correct datatypes for all uid, gid and vuid variables. Jeremy. (This used to be commit e570db46fc3a78e499523fd342e9a34cebb18998) --- source3/libsmb/clientgen.c | 76 ++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 27 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 214f6c4445..d77c58e00a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -118,7 +118,7 @@ static void cli_setup_packet(struct cli_state *cli) cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->uid); + SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { SCVAL(cli->outbuf,smb_flg,0x8); @@ -393,7 +393,10 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p += 2; pstrcpy(p,user); strupper(p); - p += 21; p++; p += 15; p++; + p += 21; + p++; + p += 15; + p++; pstrcpy(p, workstation); strupper(p); p += 16; @@ -420,8 +423,10 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) } } - if (rparam) free(rparam); - if (rdata) free(rdata); + if (rparam) + free(rparam); + if (rdata) + free(rdata); return (cli->rap_error == 0); } @@ -476,8 +481,10 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) } } - if (rparam) free(rparam); - if (rdata) free(rdata); + if (rparam) + free(rparam); + if (rdata) + free(rdata); return(count>0); } @@ -547,8 +554,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, } } - if (rparam) free(rparam); - if (rdata) free(rdata); + if (rparam) + free(rparam); + if (rdata) + free(rdata); return(count > 0); } @@ -665,8 +674,8 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - /* use the returned uid from now on */ - cli->uid = SVAL(cli->inbuf,smb_uid); + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); return True; } @@ -1690,21 +1699,23 @@ initialise a client structure ****************************************************************************/ BOOL cli_initialise(struct cli_state *cli) { - if (cli->initialised) cli_shutdown(cli); + if (cli->initialised) + cli_shutdown(cli); memset(cli, 0, sizeof(*cli)); cli->fd = -1; cli->cnum = -1; - cli->pid = getpid(); + cli->pid = (uint16)getpid(); cli->mid = 1; - cli->uid = getuid(); + cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; cli->timeout = 20000; cli->bufsize = 0x10000; cli->max_xmit = cli->bufsize - 4; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); - if (!cli->outbuf || !cli->inbuf) return False; + if (!cli->outbuf || !cli->inbuf) + return False; cli->initialised = 1; return True; } @@ -1714,12 +1725,16 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - if (cli->outbuf) free(cli->outbuf); - if (cli->inbuf) free(cli->inbuf); + if (cli->outbuf) + free(cli->outbuf); + if (cli->inbuf) + free(cli->inbuf); #ifdef WITH_SSL - if (cli->fd != -1) sslutil_disconnect(cli->fd); + if (cli->fd != -1) + sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ - if (cli->fd != -1) close(cli->fd); + if (cli->fd != -1) + close(cli->fd); memset(cli, 0, sizeof(*cli)); } @@ -1743,9 +1758,9 @@ void cli_sockopt(struct cli_state *cli, char *options) /**************************************************************************** set the PID to use for smb messages. Return the old pid. ****************************************************************************/ -int cli_setpid(struct cli_state *cli, int pid) +uint16 cli_setpid(struct cli_state *cli, uint16 pid) { - int ret = cli->pid; + uint16 ret = cli->pid; cli->pid = pid; return ret; } @@ -1826,14 +1841,16 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_session_request(cli, calling, called)) { DEBUG(1,("failed session request\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } @@ -1852,7 +1869,8 @@ BOOL cli_establish_connection(struct cli_state *cli, cli->domain)) { DEBUG(1,("failed session setup\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } if (do_tcon) @@ -1861,7 +1879,8 @@ BOOL cli_establish_connection(struct cli_state *cli, (char*)passwd, strlen(passwd))) { DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } } @@ -1883,7 +1902,8 @@ BOOL cli_establish_connection(struct cli_state *cli, cli->domain)) { DEBUG(1,("failed session setup\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } @@ -1893,13 +1913,15 @@ BOOL cli_establish_connection(struct cli_state *cli, (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) { DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } } } - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return True; } -- cgit From 5a8458c377b6901b67a039eafbd5727ed1207cf3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Sep 1998 01:05:51 +0000 Subject: libsmb/clientgen.c: Fixed signed/unsigned compile warnings spotted by Herb. param/loadparm.c: smbd/oplock.c: Allow kernel oplocks to be turned off in the smb.conf file. smbd/server.c: Move init_structs() to after the smb.conf file is loaded - preparation for making a "max open files" parameter. Jeremy. (This used to be commit 6a261517a09b005f502a37941431308fa8bf2c5c) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d77c58e00a..0892714b39 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1888,8 +1888,8 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ - char nt_sess_pwd[24]; - char lm_sess_pwd[24]; + unsigned char nt_sess_pwd[24]; + unsigned char lm_sess_pwd[24]; /* creates (storing a copy of) and then obtains a 24 byte password OWF */ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); -- cgit From 019c8d2fdda74dc03d9089eacfbd2b77e1056169 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 1998 12:36:18 +0000 Subject: several clientgen mods to support smbwrapper. In particular added cli_list() for directory listing and expended some other functions a bit. (This used to be commit 9bae21abaf3d69a204c6e617f06094303da4da48) --- source3/libsmb/clientgen.c | 275 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 272 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0892714b39..81842d920f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -847,7 +847,6 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return True; } - /**************************************************************************** create a directory ****************************************************************************/ @@ -1259,7 +1258,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) + time_t *c_time, time_t *a_time, time_t *m_time, + uint32 *size, int *mode) { int data_len = 0; int param_len = 0; @@ -1305,6 +1305,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, if (size) { *size = IVAL(rdata, 12); } + if (mode) { + *mode = SVAL(rdata,l1_attrFile); + } if (rdata) free(rdata); if (rparam) free(rparam); @@ -1376,7 +1379,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) + time_t *c_time, time_t *a_time, time_t *m_time, + uint32 *size, int *mode) { int data_len = 0; int param_len = 0; @@ -1422,12 +1426,277 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, if (size) { *size = IVAL(rdata, 12); } + if (mode) { + *mode = SVAL(rdata,l1_attrFile); + } if (rdata) free(rdata); if (rparam) free(rparam); return True; } + +/**************************************************************************** +interpret a long filename structure - this is mostly guesses at the moment +The length of the structure is returned +The structure of a long filename depends on the info level. 260 is used +by NT and 2 is used by OS/2 +****************************************************************************/ +static int interpret_long_filename(int level,char *p,file_info *finfo) +{ + extern file_info def_finfo; + + if (finfo) + memcpy(finfo,&def_finfo,sizeof(*finfo)); + + switch (level) + { + case 1: /* OS/2 understands this */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+27); + } + return(28 + CVAL(p,26)); + + case 2: /* this is what OS/2 uses mostly */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+31); + } + return(32 + CVAL(p,30)); + + /* levels 3 and 4 are untested */ + case 3: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+33); + } + return(SVAL(p,4)+4); + + case 4: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+37); + } + return(SVAL(p,4)+4); + + case 260: /* NT uses this, but also accepts 2 */ + if (finfo) { + int ret = SVAL(p,0); + int namelen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ + + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date(p); p += 8; + finfo->atime = interpret_long_date(p); p += 8; + finfo->mtime = interpret_long_date(p); p += 8; p += 8; + finfo->size = IVAL(p,0); p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL(p,0); p += 4; + namelen = IVAL(p,0); p += 4; + p += 4; /* EA size */ + p += 2; /* short name len? */ + p += 24; /* short name? */ + StrnCpy(finfo->name,p,namelen); + return(ret); + } + return(SVAL(p,0)); + } + + DEBUG(1,("Unknown long filename format %d\n",level)); + return(SVAL(p,0)); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + ****************************************************************************/ +int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *)) +{ + int max_matches = 512; + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + int info_level = cli->protocol 200) { + DEBUG(0,("Error: Looping in FIND_NEXT??\n")); + break; + } + + param_len = 12+strlen(mask)+1; + + if (First) { + setup = TRANSACT2_FINDFIRST; + SSVAL(param,0,attribute); /* attribute */ + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,6,info_level); + SIVAL(param,8,0); + pstrcpy(param+12,mask); + } else { + setup = TRANSACT2_FINDNEXT; + SSVAL(param,0,ff_dir_handle); + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,info_level); + SIVAL(param,6,ff_resume_key); /* ff_resume_key */ + SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ + pstrcpy(param+12,mask); + + DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_resume_key,ff_lastname,mask)); + } + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, 0, + cli->max_xmit /* data, length, max */ + )) { + return -1; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return -1; + } + + /* parse out some important return info */ + p = rparam; + if (First) { + ff_dir_handle = SVAL(p,0); + ff_searchcount = SVAL(p,2); + ff_eos = SVAL(p,4); + ff_lastname = SVAL(p,8); + } else { + ff_searchcount = SVAL(p,0); + ff_eos = SVAL(p,2); + ff_lastname = SVAL(p,6); + } + + if (ff_searchcount == 0) + break; + + /* point to the data bytes */ + p = rdata; + + /* we might need the lastname for continuations */ + if (ff_lastname > 0) { + switch(info_level) + { + case 260: + ff_resume_key =0; + StrnCpy(mask,p+ff_lastname, + data_len-ff_lastname); + break; + case 1: + pstrcpy(mask,p + ff_lastname + 1); + ff_resume_key = 0; + break; + } + } else { + pstrcpy(mask,""); + } + + /* and add them to the dirlist pool */ + dirlist = Realloc(dirlist,dirlist_len + data_len); + + if (!dirlist) { + DEBUG(0,("Failed to expand dirlist\n")); + break; + } + + /* put in a length for the last entry, to ensure we can chain entries + into the next packet */ + for (p2=p,i=0;i<(ff_searchcount-1);i++) + p2 += interpret_long_filename(info_level,p2,NULL); + SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); + + /* grab the data for later use */ + memcpy(dirlist+dirlist_len,p,data_len); + dirlist_len += data_len; + + total_received += ff_searchcount; + + if (rdata) free(rdata); rdata = NULL; + if (rparam) free(rparam); rparam = NULL; + + DEBUG(3,("received %d entries (eos=%d resume=%d)\n", + ff_searchcount,ff_eos,ff_resume_key)); + + First = False; + } + + for (p=dirlist,i=0;i Date: Fri, 2 Oct 1998 21:09:23 +0000 Subject: Makefile.in : - added srvsvc client files clientgen.c : - replaced cli_error(cli, int *cls, int *err) with cli_error(cli, uint8 cls, uint32 *err). this version detects 32 bit status messages. the DOS error "MORE_DATA", the equivalent of the 32 bit *warning* 0x8000 0005 (STATUS_BUFFER_OVERFLOW), was being processed as an error, terminating the cli_receive_trans() call. cli_pipe.c : - replaced calls that had been incorrectly modified from 32 bit warnings (0x8000 0005 - STATUS_BUFFER_OVERFLOW) to 8 bit DOS errors (0x01 0xEA - MORE_DATA). the use of the old version of cli_error (DOS only) instead of the new one (DOS and 32 bit) caused the dce/rpc client code to fail. - replaced 2 space indentation with tab indentation in all functions. cli_srvsvc.c : cmd_srvsvc.c : - added these files back in, fixing them up to use jeremy's modified versions of the dce/rpc client functions. parse_srv.c : - added back in some "unused" functions required by dce/rpc client-side code. it would be helpful if all such "unused" functions could be added back in. rpcclient.c : - added "session", "file", "share", "connection" enumeration functions back in. these are equivalent to nt's "NetXXXXXEnum" Win32 (MSDN) functions. - added "srvinfo" function back in. this is equivalent to nt's NetServerGetInfo Win32 (MSDN) function. (This used to be commit bcf39ffdcc64e049bca2d70a394a99976291e81d) --- source3/libsmb/clientgen.c | 162 +++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 58 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81842d920f..4c1690f6f2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -63,51 +63,61 @@ static char *cli_smb_errstr(struct cli_state *cli) char *cli_errstr(struct cli_state *cli) { - static fstring error_message; - int errclass; - int errnum; - int i; - - /* - * Errors are of three kinds - smb errors, - * dealt with by cli_smb_errstr, NT errors, - * whose code is in cli.nt_error, and rap - * errors, whose error code is in cli.rap_error. - */ + static fstring error_message; + uint8 errclass; + uint32 errnum; + int i; - cli_error(cli, &errclass, &errnum); - if(errclass != 0) - return cli_smb_errstr(cli); + /* + * Errors are of three kinds - smb errors, + * dealt with by cli_smb_errstr, NT errors, + * whose code is in cli.nt_error, and rap + * errors, whose error code is in cli.rap_error. + */ - /* - * Was it an NT error ? - */ + cli_error(cli, &errclass, &errnum); - if(cli->nt_error) { - char *nt_msg = get_nt_error_msg(cli->nt_error); + if (errclass != 0) + { + return cli_smb_errstr(cli); + } - if(nt_msg == NULL) - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); - else - fstrcpy(error_message, nt_msg); + /* + * Was it an NT error ? + */ - return error_message; - } + if (cli->nt_error) + { + char *nt_msg = get_nt_error_msg(cli->nt_error); - /* - * Must have been a rap error. - */ + if (nt_msg == NULL) + { + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); + } + else + { + fstrcpy(error_message, nt_msg); + } - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); - - for(i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->rap_error) { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; + return error_message; + } + + /* + * Must have been a rap error. + */ + + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) + { + if (rap_errmap[i].err == cli->rap_error) + { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + + return error_message; } /**************************************************************************** @@ -262,8 +272,11 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) + + if (cli_error(cli, NULL, NULL)) + { return(False); + } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -313,8 +326,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) + if (cli_error(cli, NULL, NULL)) + { return(False); + } } return(True); @@ -330,7 +345,7 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, char **rparam, uint32 *rparam_count, char **rdata, uint32 *rdata_count) { - if(pipe_name_len == 0) + if (pipe_name_len == 0) pipe_name_len = strlen(pipe_name); cli_send_trans(cli, SMBtrans, @@ -602,7 +617,7 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if(((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { /* Null session connect. */ pword[0] = '\0'; } else { @@ -620,7 +635,8 @@ BOOL cli_session_setup(struct cli_state *cli, /* send a session setup command */ bzero(cli->outbuf,smb_size); - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) + { set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -636,7 +652,9 @@ BOOL cli_session_setup(struct cli_state *cli, p += passlen; pstrcpy(p,user); strupper(p); - } else { + } + else + { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -648,11 +666,15 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + SSVAL(cli->outbuf,smb_vwv11,CAP_STATUS32); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpass,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); + if (ntpasslen != 0) + { + memcpy(p,ntpass,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); + } pstrcpy(p,user); strupper(p); p = skip_string(p,1); @@ -1718,12 +1740,12 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo char *rdata = NULL; int rprcnt, rdrcnt; - if(strlen(user) >= sizeof(fstring)-1) { + if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); return False; } - if(new_pw_len > 512) { + if (new_pw_len > 512) { DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user)); return False; } @@ -1775,7 +1797,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo data_len = 532; - if(cli_send_trans(cli,SMBtrans, + if (cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ @@ -1787,10 +1809,10 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo return False; } - if(cli_receive_trans(cli,SMBtrans, + if (cli_receive_trans(cli,SMBtrans, &rparam, &rprcnt, &rdata, &rdrcnt)) { - if(rparam) + if (rparam) cli->rap_error = SVAL(rparam,0); } @@ -1919,9 +1941,9 @@ retry: return False; #ifdef WITH_SSL - if(CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if(!sslutil_fd_is_ssl(cli->fd)){ - if(sslutil_connect(cli->fd) == 0) + if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ + if (!sslutil_fd_is_ssl(cli->fd)){ + if (sslutil_connect(cli->fd) == 0) goto retry; } } @@ -1947,7 +1969,7 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip || ip_equal(*ip, ipzero)) { - if(!resolve_name( cli->desthost, &dest_ip)) { + if (!resolve_name( cli->desthost, &dest_ip)) { return False; } } else { @@ -2007,13 +2029,37 @@ void cli_shutdown(struct cli_state *cli) memset(cli, 0, sizeof(*cli)); } + /**************************************************************************** return error codes for the last packet ****************************************************************************/ -void cli_error(struct cli_state *cli, int *eclass, int *num) +BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - *eclass = CVAL(cli->inbuf,smb_rcls); - *num = SVAL(cli->inbuf,smb_err); + int flgs2 = SVAL(cli->inbuf,smb_flg2); + + if (eclass) *eclass = 0; + if (num ) *num = 0; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { + /* 32 bit error codes detected */ + uint32 nt_err = IVAL(cli->inbuf,smb_rcls); + if (num) *num = nt_err; + DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); + return (IS_BITS_SET_ALL(nt_err, 0xc0000000)); + } + else + { + /* dos 16 bit error codes detected */ + char rcls = CVAL(cli->inbuf,smb_rcls); + if (rcls != 0) + { + if (eclass) *eclass = rcls; + if (num ) *num = SVAL(cli->inbuf,smb_err); + return True; + } + } + return False; } /**************************************************************************** -- cgit From 27e5850fd3e1c8885e54bc901cb9d79ae695466c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 08:33:07 +0000 Subject: - ignore *.p files - enable cli_RNetSharEnum - fix password handling in sesssetup for NT1 protocol - handle partial reads and writes in cli_{read,write} - added cli_getattrE - modify cli_qpathinfo() to swap byte order for win95 servers - handle temporary errors from FINDFIRST/FINDNEXT from win95 servers, when we get a error we sleep for a bit and retry - return approx unix errno from cli_error(). Need to add a lot more cases to this. (This used to be commit 715a6631c714bbd6a965e45fba1e0d0b37a27df6) --- source3/libsmb/clientgen.c | 308 ++++++++++++++++++++++++++++++++------------- 1 file changed, 221 insertions(+), 87 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4c1690f6f2..7be2717bed 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -445,7 +445,6 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } -#if UNUSED_CODE /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ @@ -501,9 +500,9 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) if (rdata) free(rdata); - return(count>0); + return count; } -#endif + /**************************************************************************** call a NetServerEnum for the specified workgroup and servertype mask. @@ -608,29 +607,38 @@ BOOL cli_session_setup(struct cli_state *cli, char *workgroup) { char *p; - fstring pword; + fstring pword, ntpword; if (cli->protocol < PROTOCOL_LANMAN1) return True; - if (passlen > sizeof(pword)-1) { + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { return False; } if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { /* Null session connect. */ pword[0] = '\0'; + ntpword[0] = '\0'; } else { if ((cli->sec_mode & 2) && passlen != 24) { passlen = 24; + ntpasslen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); } else { memcpy(pword, pass, passlen); + memcpy(ntpword, ntpass, ntpasslen); } } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} + if (!(cli->sec_mode & 1)) { + fstrcpy(pword, ""); + passlen=1; + fstrcpy(ntpword, ""); + ntpasslen=1; + } /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -670,11 +678,8 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); - if (ntpasslen != 0) - { - memcpy(p,ntpass,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); - } + memcpy(p,ntpword,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); pstrcpy(p,user); strupper(p); p = skip_string(p,1); @@ -773,6 +778,12 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } + if (cli->protocol >= PROTOCOL_NT1 && + smb_buflen(cli->inbuf) == 3) { + /* almost certainly win95 - enable bug fixes */ + cli->win95 = True; + } + cli->cnum = SVAL(cli->inbuf,smb_tid); return True; } @@ -1119,37 +1130,51 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) { char *p; + int total=0; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + while (total < size) { + int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); + int size2; - set_message(cli->outbuf,10,0,True); + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset+total); + SSVAL(cli->outbuf,smb_vwv5,size1); + SSVAL(cli->outbuf,smb_vwv6,size1); + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return total?total:-1; + } - send_smb(cli->fd,cli->outbuf); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return -1; - } + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return total?total:-1; + } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + size2 = SVAL(cli->inbuf, smb_vwv5); + if (size2 > size1) { + DEBUG(0,("server returned more than we wanted!\n")); + exit(1); + } + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + + if (size2 <= 0) break; - size = SVAL(cli->inbuf, smb_vwv5); - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf+total, p, size2); - memcpy(buf, p, size); + total += size2; + } - return size; + return total; } @@ -1159,36 +1184,100 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) { char *p; + int total=0; + while (total < size) { + int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); + int size2; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,12,size1,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset+total); + + SSVAL(cli->outbuf,smb_vwv10,size1); + SSVAL(cli->outbuf,smb_vwv11, + smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf+total, size1); + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size2 = SVAL(cli->inbuf, smb_vwv2); + + if (size2 <= 0) break; + + total += size2; + } + + return total; +} + + +/**************************************************************************** +do a SMBgetattrE call +****************************************************************************/ +BOOL cli_getattrE(struct cli_state *cli, int fd, + int *attr, uint32 *size, + time_t *c_time, time_t *a_time, time_t *m_time) +{ bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - set_message(cli->outbuf,12,size,True); + set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBwriteX; + CVAL(cli->outbuf,smb_com) = SMBgetattrE; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - - SSVAL(cli->outbuf,smb_vwv10,size); - SSVAL(cli->outbuf,smb_vwv11,smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf, size); + SSVAL(cli->outbuf,smb_vwv0,fd); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return -1; + return False; } - + if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; + return False; + } + + if (size) { + *size = IVAL(cli->inbuf, smb_vwv6); + } + + if (attr) { + *attr = SVAL(cli->inbuf,smb_vwv10); + } + + if (c_time) { + *c_time = make_unix_date3(cli->inbuf+smb_vwv0); } - return SVAL(cli->inbuf, smb_vwv2); + if (a_time) { + *a_time = make_unix_date3(cli->inbuf+smb_vwv2); + } + + if (m_time) { + *m_time = make_unix_date3(cli->inbuf+smb_vwv4); + } + + return True; } @@ -1196,7 +1285,7 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 do a SMBgetatr call ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, char *fname, - int *attr, uint32 *size, time_t *t) + uint32 *attr, size_t *size, time_t *t) { char *p; @@ -1281,13 +1370,16 @@ send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - uint32 *size, int *mode) + size_t *size, uint32 *mode) { int data_len = 0; int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; + int count=8; + BOOL ret; + time_t (*date_fn)(void *); param_len = strlen(fname) + 7; @@ -1295,34 +1387,46 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } + do { + ret = (cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + ) && + cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)); + if (!ret) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + } + } while (count-- && ret==False); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { + if (!ret || !rdata || data_len < 22) { return False; } - if (!rdata || data_len < 22) { - return False; + if (cli->win95) { + date_fn = make_unix_date; + } else { + date_fn = make_unix_date2; } if (c_time) { - *c_time = make_unix_date2(rdata+0); + *c_time = date_fn(rdata+0); } if (a_time) { - *a_time = make_unix_date2(rdata+4); + *a_time = date_fn(rdata+4); } if (m_time) { - *m_time = make_unix_date2(rdata+8); + *m_time = date_fn(rdata+8); } if (size) { *size = IVAL(rdata, 12); @@ -1579,7 +1683,7 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info int i; char *dirlist = NULL; int dirlist_len = 0; - int total_received = 0; + int total_received = -1; BOOL First = True; int ff_resume_key = 0; int ff_searchcount=0; @@ -1633,15 +1737,24 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info NULL, 0, cli->max_xmit /* data, length, max */ )) { - return -1; + break; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { - return -1; + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + continue; } + if (total_received == -1) total_received = 0; + /* parse out some important return info */ p = rparam; if (First) { @@ -1880,9 +1993,11 @@ BOOL cli_negprot(struct cli_state *cli) /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - if (IVAL(cli->inbuf,smb_vwv9+1) & 1) - cli->readbraw_supported = - cli->writebraw_supported = True; + cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); + if (cli->capabilities & 1) { + cli->readbraw_supported = True; + cli->writebraw_supported = True; + } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); @@ -2032,34 +2147,53 @@ void cli_shutdown(struct cli_state *cli) /**************************************************************************** return error codes for the last packet + returns 0 if there was no error and the bext approx of a unix errno + otherwise ****************************************************************************/ -BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { int flgs2 = SVAL(cli->inbuf,smb_flg2); + char rcls; + int code; if (eclass) *eclass = 0; if (num ) *num = 0; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) - { + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* 32 bit error codes detected */ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - return (IS_BITS_SET_ALL(nt_err, 0xc0000000)); + if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; + + switch (nt_err & 0xFFFFFF) { + case NT_STATUS_ACCESS_VIOLATION: return EPERM; + } + + /* for all other cases - a default code */ + return EINVAL; } - else - { - /* dos 16 bit error codes detected */ - char rcls = CVAL(cli->inbuf,smb_rcls); - if (rcls != 0) - { - if (eclass) *eclass = rcls; - if (num ) *num = SVAL(cli->inbuf,smb_err); - return True; + + rcls = CVAL(cli->inbuf,smb_rcls); + code = SVAL(cli->inbuf,smb_err); + if (rcls == 0) return 0; + + if (eclass) *eclass = rcls; + if (num ) *num = code; + + if (rcls == ERRDOS) { + switch (code) { + case ERRbadfile: return ENOENT; + case ERRnoaccess: return EPERM; + } + } + if (rcls == ERRSRV) { + switch (code) { + case ERRbadpw: return EPERM; } } - return False; + /* for other cases */ + return EINVAL; } /**************************************************************************** -- cgit From cce5f09a90b5027bafd22f42edab9c256789bce1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 09:39:11 +0000 Subject: added unlink() and rename() support to smbwrapper (This used to be commit b85d96144728e8a29c7c1114462e28bf3b144b80) --- source3/libsmb/clientgen.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7be2717bed..d2a7749490 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -448,7 +448,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *)) +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, char *)) { char *rparam = NULL; char *rdata = NULL; @@ -807,11 +807,10 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } -#if UNUSED_CODE /**************************************************************************** rename a file ****************************************************************************/ -BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) { char *p; @@ -844,7 +843,6 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) return True; } -#endif /**************************************************************************** delete a file @@ -2167,7 +2165,13 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EPERM; + case NT_STATUS_ACCESS_VIOLATION: return EACCES; + case NT_STATUS_NO_SUCH_FILE: return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; + case NT_STATUS_INVALID_HANDLE: return EBADF; + case NT_STATUS_NO_MEMORY: return ENOMEM; + case NT_STATUS_ACCESS_DENIED: return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; } /* for all other cases - a default code */ -- cgit From 4fedb9ddd5440c546145e8c9950ef938c52bdfe0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 11:53:37 +0000 Subject: - always open for reading (otherwise getattrE won't work). - added somemore NT error codes (This used to be commit a0632529133fdaff9d70ac3e0cf6bb021c79438e) --- source3/libsmb/clientgen.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d2a7749490..0a61a74cce 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -953,6 +953,12 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) unsigned openfn=0; unsigned accessmode=0; + /* you must open for RW not just write - otherwise getattrE doesn't + work! */ + if ((flags & O_ACCMODE) == O_WRONLY) { + flags = (flags & ~O_ACCMODE) | O_RDWR; + } + if (flags & O_CREAT) openfn |= (1<<4); if (!(flags & O_EXCL)) { @@ -964,9 +970,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) accessmode = (share_mode<<4); - if ((flags & O_RDWR) == O_RDWR) { + if ((flags & O_ACCMODE) == O_RDWR) { accessmode |= 2; - } else if ((flags & O_WRONLY) == O_WRONLY) { + } else if ((flags & O_ACCMODE) == O_WRONLY) { accessmode |= 1; } @@ -1503,8 +1509,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - time_t *c_time, time_t *a_time, time_t *m_time, - uint32 *size, int *mode) + uint32 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time) { int data_len = 0; int param_len = 0; @@ -2172,6 +2178,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case NT_STATUS_NO_MEMORY: return ENOMEM; case NT_STATUS_ACCESS_DENIED: return EACCES; case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION: return EBUSY; } /* for all other cases - a default code */ -- cgit From 03a06267f4674201c107b85abf993688312c5093 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 13:12:08 +0000 Subject: added simple device/inode number support based on a checksum of the filename (This used to be commit 5674fb4e9dc4d92213d763c8cecd26efc23a9720) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0a61a74cce..bd044f4e26 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -448,7 +448,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, char *)) +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; -- cgit From f2d8f110db994588cb85a9c0c22c0941f4ccca38 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 15:01:11 +0000 Subject: fixed vi on smbwrappper (it was a problem in cli_read()) (This used to be commit 1dcc84b942d4669f978aebdeaf85ea609c2b732f) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bd044f4e26..6132114ac6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1131,7 +1131,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int /**************************************************************************** read from a file ****************************************************************************/ -int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; int total=0; @@ -1185,7 +1185,7 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s /**************************************************************************** write to a file ****************************************************************************/ -int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; int total=0; -- cgit From 8d4c7326212f23d2a255def7f7e9c992eb752911 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 15:55:18 +0000 Subject: fixed a authentication problem with non-encrypting servers (This used to be commit 06f1af12c37fc759e7315366dd4e82f4e96b042d) --- source3/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6132114ac6..dc60b6951c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -627,8 +627,9 @@ BOOL cli_session_setup(struct cli_state *cli, SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); } else { - memcpy(pword, pass, passlen); - memcpy(ntpword, ntpass, ntpasslen); + fstrcpy(pword, pass); + fstrcpy(ntpword, ""); + ntpasslen = 0; } } -- cgit From a1e10cfc3cb8416224bbc63fba83e4f50ce75a06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 03:27:04 +0000 Subject: use const char (This used to be commit 83b7bfa821b88f0826b348ec493141a324e12a86) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index dc60b6951c..1d2ea199c0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -259,7 +259,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int this_data,this_param; *data_len = *param_len = 0; - + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -1373,7 +1373,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) /**************************************************************************** send a qpathinfo call ****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, char *fname, +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint32 *mode) { -- cgit From 5ade894f32377ffaed3fc085810892509a6e8c66 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 06:22:08 +0000 Subject: modified cli_read() and cli_write() to issue multiple outstanding read/write requests for large reads. up to max_mux requests may be outstanding. This gives _much_ better throughput and should allow smbsh to saturate just about any network. this is an implementation of the "fast SMB" method I described on the CIFS list a couple of months back. (This used to be commit c728d1c5d6e4626d2f8e318eab4df32acc8cb505) --- source3/libsmb/clientgen.c | 188 ++++++++++++++++++++++++++++++++------------- 1 file changed, 133 insertions(+), 55 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1d2ea199c0..cd6d295094 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1129,108 +1129,185 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int } + +/**************************************************************************** +issue a single SMBread and don't wait for a reply +****************************************************************************/ +static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + send_smb(cli->fd,cli->outbuf); +} + /**************************************************************************** read from a file ****************************************************************************/ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; - int total=0; - - while (total < size) { - int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); + int total = -1; + int issued=0; + int received=0; + int mpx = MAX(cli->max_mux-1, 1); + int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int mid; + int blocks = (size + (block-1)) / block; + + while (received < blocks) { int size2; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); - - set_message(cli->outbuf,10,0,True); - - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset+total); - SSVAL(cli->outbuf,smb_vwv5,size1); - SSVAL(cli->outbuf,smb_vwv6,size1); + while (issued - received < mpx && issued < blocks) { + int size1 = MIN(block, size-issued*block); + cli_issue_read(cli, fnum, offset+issued*block, size1, issued); + issued++; + } - send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return total?total:-1; + return total; } + received++; + mid = SVAL(cli->inbuf, smb_mid) - cli->mid; + size2 = SVAL(cli->inbuf, smb_vwv5); + if (CVAL(cli->inbuf,smb_rcls) != 0) { - return total?total:-1; + blocks = MIN(blocks, mid-1); + continue; } - size2 = SVAL(cli->inbuf, smb_vwv5); - if (size2 > size1) { + if (size2 <= 0) { + blocks = MIN(blocks, mid-1); + /* this distinguishes EOF from an error */ + total = MAX(total, 0); + continue; + } + + if (size2 > block) { DEBUG(0,("server returned more than we wanted!\n")); exit(1); } + if (mid >= issued) { + DEBUG(0,("invalid mid from server!\n")); + exit(1); + } p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - if (size2 <= 0) break; + memcpy(buf+mid*block, p, size2); - memcpy(buf+total, p, size2); - - total += size2; + total = MAX(total, mid*block + size2); } + while (received < issued) { + client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + received++; + } + return total; } /**************************************************************************** - write to a file +issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char *buf, + size_t size, int i) { char *p; - int total=0; - - while (total < size) { - int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); - int size2; - - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); - set_message(cli->outbuf,12,size1,True); + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); - CVAL(cli->outbuf,smb_com) = SMBwriteX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + set_message(cli->outbuf,12,size,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + + SSVAL(cli->outbuf,smb_vwv10,size); + SSVAL(cli->outbuf,smb_vwv11, + smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf, size); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset+total); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + send_smb(cli->fd,cli->outbuf); +} - SSVAL(cli->outbuf,smb_vwv10,size1); - SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf)); +/**************************************************************************** + write to a file +****************************************************************************/ +size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +{ + int total = -1; + int issued=0; + int received=0; + int mpx = MAX(cli->max_mux-1, 1); + int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int mid; + int blocks = (size + (block-1)) / block; + + while (received < blocks) { + int size2; - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf+total, size1); + while (issued - received < mpx && issued < blocks) { + int size1 = MIN(block, size-issued*block); + cli_issue_write(cli, fnum, offset+issued*block, buf + issued*block, + size1, issued); + issued++; + } - send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return -1; + return total; } + received++; + mid = SVAL(cli->inbuf, smb_mid) - cli->mid; + size2 = SVAL(cli->inbuf, smb_vwv2); + if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; + blocks = MIN(blocks, mid-1); + continue; } - size2 = SVAL(cli->inbuf, smb_vwv2); - - if (size2 <= 0) break; + if (size2 <= 0) { + blocks = MIN(blocks, mid-1); + /* this distinguishes EOF from an error */ + total = MAX(total, 0); + continue; + } total += size2; + + total = MAX(total, mid*block + size2); } + while (received < issued) { + client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + received++; + } + return total; } @@ -1992,6 +2069,7 @@ BOOL cli_negprot(struct cli_state *cli) if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); + cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; -- cgit From f3db9286f98a8d5ab2310fca73e89f0f2732704e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 06:43:41 +0000 Subject: fix an error code in cli_error() (This used to be commit bbc891727e57172bf6200e10c32498776a77510b) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cd6d295094..4ce86eeb2c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2274,7 +2274,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (rcls == ERRDOS) { switch (code) { case ERRbadfile: return ENOENT; - case ERRnoaccess: return EPERM; + case ERRnoaccess: return EACCES; } } if (rcls == ERRSRV) { -- cgit From 52e5dbeb9c4a59bf47d75e5b693146951e16ba44 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 07:51:34 +0000 Subject: use CLI_BUFFER_SIZE instead of BUFFER_SIZE (This used to be commit 98f9bb94fcdd0195158eba0deaebe4679baea44c) --- source3/libsmb/clientgen.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4ce86eeb2c..e871bd7d9d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -415,14 +415,14 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) pstrcpy(p, workstation); strupper(p); p += 16; - SSVAL(p, 0, BUFFER_SIZE); + SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; - SSVAL(p, 0, BUFFER_SIZE); + SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; if (cli_api(cli, param, PTR_DIFF(p,param),1024, /* param, length, max */ - NULL, 0, BUFFER_SIZE, /* data, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { @@ -466,12 +466,12 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,BUFFER_SIZE); + SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, BUFFER_SIZE, /* data, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { @@ -533,7 +533,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = skip_string(p,1); SSVAL(p,0,uLevel); - SSVAL(p,2,BUFFER_SIZE); + SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; SIVAL(p,0,stype); p += 4; @@ -543,7 +543,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, BUFFER_SIZE, /* data, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { @@ -669,7 +669,7 @@ BOOL cli_session_setup(struct cli_state *cli, cli_setup_packet(cli); CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); @@ -2097,6 +2097,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = TimeDiff(time(NULL)); } + cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); + return True; } @@ -2199,8 +2201,8 @@ BOOL cli_initialise(struct cli_state *cli) cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; cli->timeout = 20000; - cli->bufsize = 0x10000; - cli->max_xmit = cli->bufsize - 4; + cli->bufsize = CLI_BUFFER_SIZE+4; + cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); if (!cli->outbuf || !cli->inbuf) -- cgit From 6760e69a68571e01ee57b959193a56278962a23c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 09:42:51 +0000 Subject: added support for printing via smbwrapper You can print using "cp filename /smb/SERVER/PRINTER/jobname" You can list the current printqueue using ls (This used to be commit 080fb61b69620e26e8122705383dc2bd0468a519) --- source3/libsmb/clientgen.c | 100 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e871bd7d9d..0e01370f5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -137,6 +137,29 @@ static void cli_setup_packet(struct cli_state *cli) } +/***************************************************************************** + Convert a character pointer in a cli_call_api() response to a form we can use. + This function contains code to prevent core dumps if the server returns + invalid data. +*****************************************************************************/ +static char *fix_char_ptr(unsigned int datap, unsigned int converter, + char *rdata, int rdrcnt) +{ + if (datap == 0) { /* turn NULL pointers into zero length strings */ + return ""; + } else { + unsigned int offset = datap - converter; + + if (offset >= rdrcnt) { + DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", + datap, converter, rdrcnt)); + return ""; + } else { + return &rdata[offset]; + } + } +} + /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ @@ -739,6 +762,8 @@ BOOL cli_send_tconX(struct cli_state *cli, bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); + fstrcpy(cli->share, share); + if (cli->sec_mode & 1) { passlen = 1; pass = ""; @@ -779,6 +804,8 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } + fstrcpy(cli->dev, smb_buf(cli->inbuf)); + if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ @@ -2466,3 +2493,76 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } + + + +/**************************************************************************** +call fn() on each entry in a print queue +****************************************************************************/ +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int result_code=0; + int i = -1; + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ + p += 2; + pstrcpy(p,"zWrLeh"); /* parameter description? */ + p = skip_string(p,1); + pstrcpy(p,"WWzWWDDzz"); /* returned data format */ + p = skip_string(p,1); + pstrcpy(p,cli->share); /* name of queue */ + p = skip_string(p,1); + SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ + SSVAL(p,2,1000); /* size of bytes of returned data buffer */ + p += 4; + pstrcpy(p,""); /* subformat */ + p = skip_string(p,1); + + DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) { /* return data, length */ + int converter; + result_code = SVAL(rparam,0); + converter = SVAL(rparam,2); /* conversion factor */ + + if (result_code == 0) { + struct print_job_info job; + + p = rdata; + + for (i = 0; i < SVAL(rparam,4); ++i) { + job.id = SVAL(p,0); + job.priority = SVAL(p,2); + fstrcpy(job.user, + fix_char_ptr(SVAL(p,4), converter, + rdata, rdrcnt)); + job.t = make_unix_date3(p + 12); + job.size = IVAL(p,16); + fstrcpy(job.name,fix_char_ptr(SVAL(p,24), + converter, + rdata, rdrcnt)); + fn(&job); + p += 28; + } + } + } + + /* If any parameters or data were returned, free the storage. */ + if(rparam) free(rparam); + if(rdata) free(rdata); + + return i; +} -- cgit From a1b002fcbe5daa91ce8bc94b73760e2428238315 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 10:14:21 +0000 Subject: add support for unlink() on printer shares in smbwrapper. unlink() will remove the job from the pirnt queue. (This used to be commit 7bd738c30a09a211fd14a8544309efeec17c66f5) --- source3/libsmb/clientgen.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0e01370f5d..e4aa15c6eb 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2495,6 +2495,43 @@ BOOL cli_establish_connection(struct cli_state *cli, } +/**************************************************************************** + cancel a print job + ****************************************************************************/ +int cli_printjob_del(struct cli_state *cli, int job) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt, ret = -1; + pstring param; + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,81); /* DosPrintJobDel() */ + p += 2; + pstrcpy(p,"W"); + p = skip_string(p,1); + pstrcpy(p,""); + p = skip_string(p,1); + SSVAL(p,0,job); + p += 2; + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) { /* return data, length */ + ret = SVAL(rparam,0); + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return ret; +} + /**************************************************************************** call fn() on each entry in a print queue -- cgit From 7c3c022a8913aec76a175095475cfcf8a4dfd698 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 10:46:52 +0000 Subject: use *SMBSERVER convention in smbwrapper to allow us to connect to servers that we don't know the netbios name of. (This used to be commit 147d49dade3901835b5d60b02c495bea544ff5e9) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e4aa15c6eb..20c0c36166 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2134,7 +2134,7 @@ BOOL cli_negprot(struct cli_state *cli) send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called) + struct nmb_name *calling, struct nmb_name *called) { char *p; int len = 4; -- cgit From 1970c92c0a56672308314d39718f994302c95c95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 11:25:06 +0000 Subject: support NetServerEnum in smbwrapper. You can now do a ls in /smb/ and it will list all servers in your workgroup. You can set your workgroup with the SMBW_WORKGROUP environment variable. (This used to be commit 64699810e2d94e8648a0a3341b1cc826d4e8bfd9) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 20c0c36166..6b07eb65b3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -535,7 +535,7 @@ The callback function takes 3 arguments: the machine name, the server type and the comment. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(char *, uint32, char *)) + void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; -- cgit From 40984f6b55212c710f6a7c7b940a785b2b607985 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 12:00:40 +0000 Subject: - modified resolve_name() to take a name_type - cleaned up resolve_name() (split into separate functions for each resolver) - if can't find local master then use #1B name - support listing of foreign workgroups in /smb/ (This used to be commit a4e607c17d1119925c9d0e1d05e0fe81e9a2d1aa) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6b07eb65b3..100e90160d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2196,7 +2196,7 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &dest_ip)) { + if (!resolve_name( cli->desthost, &dest_ip, 0x20)) { return False; } } else { -- cgit From ecb7ee7a034961a38a2922f481a3235c615903bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Oct 1998 02:45:50 +0000 Subject: handle ENOTDIR errno in cli_error() (This used to be commit f1d82e02ff7f2201de5fb13af4cadec648765017) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 100e90160d..46da08bb3a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2287,6 +2287,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case NT_STATUS_ACCESS_DENIED: return EACCES; case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; case NT_STATUS_SHARING_VIOLATION: return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; } /* for all other cases - a default code */ @@ -2303,6 +2304,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (rcls == ERRDOS) { switch (code) { case ERRbadfile: return ENOENT; + case ERRbadpath: return ENOTDIR; case ERRnoaccess: return EACCES; } } -- cgit From bfaff8ed1a3899c9aef7eaa2421d3d6467343ea1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Oct 1998 12:17:01 +0000 Subject: got smbwrapper working on IRIX 6.4. Things got a bit tricky, especially as the headers get the syscall numbers wrong! (This used to be commit a5405f1ab069a3123a819311a87ca84f2c5f0fea) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 46da08bb3a..e395aa3b15 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1343,7 +1343,7 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ do a SMBgetattrE call ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - int *attr, uint32 *size, + uint32 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { bzero(cli->outbuf,smb_size); -- cgit From b4fb4caf9032875fe50725c9b71b6411538ba85f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 5 Oct 1998 15:41:41 +0000 Subject: rpcclient srvsvc commands. (This used to be commit 1a9a22c657c46648adaa98ac1fe394ce4bce11f0) --- source3/libsmb/clientgen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e395aa3b15..2d49144695 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2259,8 +2259,11 @@ void cli_shutdown(struct cli_state *cli) /**************************************************************************** return error codes for the last packet - returns 0 if there was no error and the bext approx of a unix errno + returns 0 if there was no error and the best approx of a unix errno otherwise + + for 32 bit "warnings", a return code of 0 is expected. + ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { -- cgit From 404f14fb36577ee182fd8a928e6cb7b374e4ecb9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 1998 13:10:06 +0000 Subject: implemented unix semantics for rename in smbwrapper (This used to be commit a5c18f9c82f5f76b00ff29c5668b4f0d3e8d6bd0) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2d49144695..93f7a3d222 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1196,6 +1196,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int mid; int blocks = (size + (block-1)) / block; + if (size == 0) return 0; + while (received < blocks) { int size2; @@ -1295,6 +1297,8 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ int mid; int blocks = (size + (block-1)) / block; + if (size == 0) return 0; + while (received < blocks) { int size2; @@ -2309,6 +2313,8 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRbadfile: return ENOENT; case ERRbadpath: return ENOTDIR; case ERRnoaccess: return EACCES; + case ERRfilexists: return EEXIST; + case ERRrename: return EEXIST; } } if (rcls == ERRSRV) { -- cgit From cbb25c71d052c5fc2f4d526625d558f0c33f587e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 1998 13:20:06 +0000 Subject: fixed rename error code from NT servers (This used to be commit e7516901270a4a790a3e346065eb2be8ede16cb3) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 93f7a3d222..70231e3c94 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2295,6 +2295,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; case NT_STATUS_SHARING_VIOLATION: return EBUSY; case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; } /* for all other cases - a default code */ -- cgit From 029144cd8c07aa82100b545574e3af1201426b58 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Oct 1998 00:40:18 +0000 Subject: do an anonymous login if the username/password is rejected. (This used to be commit 0ee3e0c62378bdf7a8e145de0727ea85763af95a) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 70231e3c94..38b4b5ffeb 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -764,6 +764,7 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->share, share); + /* in user level security don't send a password now */ if (cli->sec_mode & 1) { passlen = 1; pass = ""; -- cgit From 4750ce1760a39100f71e74ce8b88a925fef4c42f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 02:28:21 +0000 Subject: use 1 second resolution calls if possible (This used to be commit 349469221a84658048790d7567b4fcea43c0b759) --- source3/libsmb/clientgen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 38b4b5ffeb..657523b3be 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1557,9 +1557,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, uint32 *size) + time_t *w_time, size_t *size, uint32 *mode) { int data_len = 0; int param_len = 0; @@ -1608,6 +1608,9 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, if (size) { *size = IVAL(rdata, 40); } + if (mode) { + *mode = IVAL(rdata, 32); + } if (rdata) free(rdata); if (rparam) free(rparam); -- cgit From 788263ba2f749c5bb1546ca6c9363fd508e94280 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 06:21:33 +0000 Subject: - fixed a bunch of warnings and minor errors - got smbtorture to compile - removed %D from some of lukes code - Luke, what is %D? it ain't portable anyway (This used to be commit 91597c12fb593f49b23c7cea5b64dbb89a0428b3) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 657523b3be..d454cbdd3c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -621,7 +621,7 @@ prots[] = /**************************************************************************** -send a session setup +send a session setup ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, char *user, -- cgit From a813f38e2dc894b548c23dea2bef98cef7d4f4e9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 06:49:00 +0000 Subject: - don't generate 0 params in torture - handle 0 params in ipc.c (This used to be commit c0dc8e87f0d56444a8ddff0817a94065ca295847) --- source3/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d454cbdd3c..8aa857df8a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -432,9 +432,9 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) pstrcpy(p,user); strupper(p); p += 21; - p++; - p += 15; - p++; + p++; + p += 15; + p++; pstrcpy(p, workstation); strupper(p); p += 16; -- cgit From 6909350ed9b87875ee40191b2e636c6049749195 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 8 Oct 1998 23:57:46 +0000 Subject: dce/rpc (This used to be commit 62fdeef1b79c5c4c9bf0e860881651711bb80b9a) --- source3/libsmb/clientgen.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8aa857df8a..5ae84f763b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1255,7 +1255,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char *buf, +static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, size_t size, int i) { char *p; @@ -1272,6 +1272,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); + SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); + SSVAL(cli->outbuf,smb_vwv7,mode); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, @@ -1282,13 +1284,20 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char SSVAL(cli->outbuf,smb_mid,cli->mid + i); + show_msg(cli->outbuf); send_smb(cli->fd,cli->outbuf); } /**************************************************************************** write to a file + write_mode: 0x0001 disallow write cacheing + 0x0002 return bytes remaining + 0x0004 use raw named pipe protocol + 0x0008 start of message mode named pipe protocol ****************************************************************************/ -size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +size_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size) { int total = -1; int issued=0; @@ -1305,7 +1314,9 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ while (issued - received < mpx && issued < blocks) { int size1 = MIN(block, size-issued*block); - cli_issue_write(cli, fnum, offset+issued*block, buf + issued*block, + cli_issue_write(cli, fnum, offset+issued*block, + write_mode, + buf + issued*block, size1, issued); issued++; } @@ -2226,9 +2237,12 @@ initialise a client structure BOOL cli_initialise(struct cli_state *cli) { if (cli->initialised) - cli_shutdown(cli); + { + cli_shutdown(cli); + } memset(cli, 0, sizeof(*cli)); + cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)getpid(); @@ -2241,8 +2255,12 @@ BOOL cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); if (!cli->outbuf || !cli->inbuf) - return False; + { + return False; + } + cli->initialised = 1; + return True; } @@ -2252,9 +2270,13 @@ shutdown a client structure void cli_shutdown(struct cli_state *cli) { if (cli->outbuf) - free(cli->outbuf); + { + free(cli->outbuf); + } if (cli->inbuf) - free(cli->inbuf); + { + free(cli->inbuf); + } #ifdef WITH_SSL if (cli->fd != -1) sslutil_disconnect(cli->fd); @@ -2454,7 +2476,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session setup\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } if (do_tcon) @@ -2464,7 +2488,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } } -- cgit From 4e004a0b5e7521a361444f6d67a3c2910c5688c2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 19:34:57 +0000 Subject: basic client-side ntcreateX function (hard-wired values except filename) (This used to be commit caeb99201a1471bd709b4e8f07c57e5caabf0795) --- source3/libsmb/clientgen.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5ae84f763b..8eb832128c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -973,6 +973,50 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) +/**************************************************************************** +open a file +****************************************************************************/ +int cli_nt_create(struct cli_state *cli, char *fname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,24,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBntcreateX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); + SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); + SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); + SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); + SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); + + p = smb_buf(cli->outbuf); + pstrcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2 + 1); +} + + /**************************************************************************** open a file ****************************************************************************/ -- cgit From 8158620124504a1ece1f1191cb8f273709039bd2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 20:17:11 +0000 Subject: dce/rpc. (This used to be commit e0445419b2d50ae6efef36f4f295ebcfdbf1ad82) --- source3/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8eb832128c..025ec5e73f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -614,8 +614,8 @@ prots[] = {PROTOCOL_LANMAN1,"LANMAN1.0"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LM 0.12"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, {-1,NULL} }; @@ -1318,7 +1318,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SIVAL(cli->outbuf,smb_vwv3,offset); SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); SSVAL(cli->outbuf,smb_vwv7,mode); - + + SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); -- cgit From 78c1fd054f25ae2d0fa57669a0db102bc916577c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 23:31:50 +0000 Subject: dce/rpc (This used to be commit 8a7ac4a25d177235a98c0f84f97ee50432fb6359) --- source3/libsmb/clientgen.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 025ec5e73f..72d7ca935b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2021,7 +2021,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo unsigned char new_pw_hash[16]; int data_len; int param_len = 0; - int new_pw_len = strlen(new_password); char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; @@ -2031,11 +2030,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo return False; } - if (new_pw_len > 512) { - DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user)); - return False; - } - SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; pstrcpy(p, "zsT"); @@ -2049,26 +2043,19 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo param_len = PTR_DIFF(p,param); - /* - * Now setup the data area. - * We need to generate a random fill - * for this area to make it harder to - * decrypt. JRA. - */ - generate_random_buffer((unsigned char *)data, sizeof(data), False); - fstrcpy( &data[512 - new_pw_len], new_password); - SIVAL(data, 512, new_pw_len); - /* * Get the Lanman hash of the old password, we - * use this as the key to SamOEMHash(). + * use this as the key to make_oem_passwd_hash(). */ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); fstrcpy(upper_case_old_pw, old_password); strupper(upper_case_old_pw); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + if (!make_oem_passwd_hash( data, new_password, old_pw_hash)) + { + return False; + } /* * Now place the old password hash in the data. -- cgit From 827a9d862ebe3d5ce1853999d16bd121fddcc796 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 10 Oct 1998 00:46:28 +0000 Subject: dce/rpc (This used to be commit dfb48aab6153e53a5efd1f8ee518375cc584b101) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 72d7ca935b..64e67c5522 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2052,7 +2052,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo strupper(upper_case_old_pw); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - if (!make_oem_passwd_hash( data, new_password, old_pw_hash)) + if (!make_oem_passwd_hash( data, new_password, old_pw_hash, False)) { return False; } -- cgit From c404bb775414139a4b07a73f79cf069a083acb26 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Oct 1998 23:51:07 +0000 Subject: rpcclient interactive login (with trust account changing if you are root) cli_session_setup handles null sessions correctly (This used to be commit 60c0f22a4e84703467006dfe1971384a6294a9aa) --- source3/libsmb/clientgen.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 64e67c5522..a6ffb57834 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2494,15 +2494,25 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { - /* attempt clear-text session */ - fstring passwd; + int pass_len; - pwd_get_cleartext(&(cli->pwd), passwd); + if (cli->pwd.null_pwd) + { + /* attempt null session */ + passwd[0] = 0; + pass_len = 1; + } + else + { + /* attempt clear-text session */ + pwd_get_cleartext(&(cli->pwd), passwd); + pass_len = strlen(passwd); + } /* attempt clear-text session */ if (!cli_session_setup(cli, cli->user_name, - passwd, strlen(passwd), + passwd, pass_len, NULL, 0, cli->domain)) { -- cgit From 070b33489179d07ed76530ad52b828e6e708789d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Oct 1998 00:54:16 +0000 Subject: trans2.h: Added Thursby MAC extension. smbd/trans2.c: Added Thursby MAX extension. libsmb/clientgen.c: Fixed smbtorture lock code. Jeremy. (This used to be commit 514e52e4b4d6c7db7ebe2265e60c77b4f18d11b3) --- source3/libsmb/clientgen.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a6ffb57834..3c2ad3e0ea 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1126,6 +1126,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) { char *p; + int saved_timeout = cli->timeout; bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); @@ -1149,10 +1150,16 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SIVAL(p, 6, len); send_smb(cli->fd,cli->outbuf); + + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + cli->timeout = saved_timeout; return False; } + cli->timeout = saved_timeout; + if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; } @@ -1315,6 +1322,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); SSVAL(cli->outbuf,smb_vwv7,mode); -- cgit From 62811de4e84f21aafff161dbf151e487660144e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Oct 1998 17:40:01 +0000 Subject: - use large buffers for netshareenum - handle errmoredata a bit better - fix dev type from tconx for smbw (This used to be commit 2f39409dc1ef012a8a7d315572a489d15df186f7) --- source3/libsmb/clientgen.c | 49 ++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3c2ad3e0ea..3ed80eb7a6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -489,12 +489,12 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,CLI_BUFFER_SIZE); + SSVAL(p,2,0xFFFF); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + NULL, 0, 0xFFFF, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { @@ -502,20 +502,22 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c int converter=SVAL(rparam,2); int i; - if (res == 0) - { - count=SVAL(rparam,4); - p = rdata; - - for (i=0;ioutbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,CAP_STATUS32); + SSVAL(cli->outbuf,smb_vwv11,0); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); @@ -805,8 +807,17 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } - fstrcpy(cli->dev, smb_buf(cli->inbuf)); + fstrcpy(cli->dev, "A:"); + + if (cli->protocol >= PROTOCOL_NT1) { + fstrcpy(cli->dev, smb_buf(cli->inbuf)); + } + + if (strcasecmp(share,"IPC$")==0) { + fstrcpy(cli->dev, "IPC"); + } + /* only grab the device if we have a recent protocol level */ if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ -- cgit From d5c190bae83b49de7bb8b626f83fc730f8759270 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Oct 1998 01:05:11 +0000 Subject: return the resolved IP on a cli_connect() call so it can be cached (This used to be commit 4e3f8ef41b8de25dec4c01d5532dca1b567be55a) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3ed80eb7a6..48abbd7a15 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2269,6 +2269,7 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) if (!resolve_name( cli->desthost, &dest_ip, 0x20)) { return False; } + if (ip) *ip = dest_ip; } else { dest_ip = *ip; } -- cgit From 9debf0b1eeeb6766e3f8ad5b62cf41c7194e41ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Oct 1998 02:48:57 +0000 Subject: improved session reestablishment (This used to be commit 5f96328d32e76785474ffd5cd73f8ddefc46d4f5) --- source3/libsmb/clientgen.c | 118 +++++++++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 36 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 48abbd7a15..7c58a969e7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -27,6 +27,40 @@ extern int DEBUGLEVEL; + +/**************************************************************************** + send an smb to a fd and re-establish if necessary +****************************************************************************/ +static BOOL cli_send_smb(struct cli_state *cli) +{ + size_t len; + size_t nwritten=0; + ssize_t ret; + BOOL reestablished=False; + + len = smb_len(cli->outbuf) + 4; + + while (nwritten < len) { + ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + if (ret <= 0 && errno == EPIPE && !reestablished) { + if (cli_reestablish_connection(cli)) { + reestablished = True; + nwritten=0; + continue; + } + } + if (ret <= 0) { + DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", + len,ret)); + close_sockets(); + exit(1); + } + nwritten += ret; + } + + return True; +} + /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -218,7 +252,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); show_msg(cli->outbuf); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -259,7 +293,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); show_msg(cli->outbuf); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); tot_data += this_ldata; tot_param += this_lparam; @@ -717,7 +751,7 @@ BOOL cli_session_setup(struct cli_state *cli, set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -730,6 +764,8 @@ BOOL cli_session_setup(struct cli_state *cli, /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); + fstrcpy(cli->user_name, user); + return True; } @@ -746,7 +782,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -799,7 +835,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -840,7 +876,7 @@ BOOL cli_tdis(struct cli_state *cli) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -872,7 +908,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) *p++ = 4; pstrcpy(p,fname_dst); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -906,7 +942,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) *p++ = 4; pstrcpy(p,fname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -938,7 +974,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -970,7 +1006,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1015,7 +1051,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) pstrcpy(p,fname); p = skip_string(p,1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -1086,7 +1122,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) pstrcpy(p,fname); p = skip_string(p,1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -1118,7 +1154,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1160,7 +1196,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SIVAL(p, 2, offset); SIVAL(p, 6, len); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1206,7 +1242,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1242,7 +1278,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); } /**************************************************************************** @@ -1349,7 +1385,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); show_msg(cli->outbuf); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); } /**************************************************************************** @@ -1437,7 +1473,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1491,7 +1527,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, *p = 4; pstrcpy(p+1, fname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1542,7 +1578,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) p = skip_string(p,1); *p = 4; - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -2149,7 +2185,7 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -2231,7 +2267,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); DEBUG(5,("Sent session request\n")); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) @@ -2260,22 +2296,22 @@ open the client sockets ****************************************************************************/ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { - struct in_addr dest_ip; extern struct in_addr ipzero; fstrcpy(cli->desthost, host); if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &dest_ip, 0x20)) { + if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { return False; } - if (ip) *ip = dest_ip; + if (ip) *ip = cli->dest_ip; } else { - dest_ip = *ip; + cli->dest_ip = *ip; } - cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + 139, cli->timeout); if (cli->fd == -1) return False; @@ -2424,17 +2460,17 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) } /**************************************************************************** -establishes a connection right up to doing tconX, reading in a password. +re-establishes a connection ****************************************************************************/ BOOL cli_reestablish_connection(struct cli_state *cli) { struct nmb_name calling; struct nmb_name called; fstring dest_host; - struct in_addr dest_ip; fstring share; fstring dev; BOOL do_tcon = False; + int oldfd = cli->fd; if (!cli->initialised || cli->fd == -1) { @@ -2454,16 +2490,26 @@ BOOL cli_reestablish_connection(struct cli_state *cli) memcpy(&called , &(cli->called ), sizeof(called )); memcpy(&calling, &(cli->calling), sizeof(calling)); fstrcpy(dest_host, cli->full_dest_host_name); - dest_ip = cli->dest_ip; DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - namestr(&calling), namestr(&called), inet_ntoa(dest_ip), - cli->user_name, cli->domain)); + namestr(&calling), namestr(&called), + inet_ntoa(cli->dest_ip), + cli->user_name, cli->domain)); - return cli_establish_connection(cli, - dest_host, &dest_ip, - &calling, &called, - share, dev, False, do_tcon); + cli->fd = -1; + + if (cli_establish_connection(cli, + dest_host, &cli->dest_ip, + &calling, &called, + share, dev, False, do_tcon)) { + if (cli->fd != oldfd) { + if (dup2(cli->fd, oldfd) == oldfd) { + close(cli->fd); + } + } + return True; + } + return False; } /**************************************************************************** -- cgit From 01de6030843f5f402dee8bf72f564a91ae8437ca Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 19 Oct 1998 17:32:10 +0000 Subject: - dce/rpc code - removed debug info in struni2 and unistr2 (security risk) - rpc_pipe function was getting pointer to data then calling realloc *dur* - password check function, the start of "credential checking", user, wks, domain, pass as the credentials (not just user,pass which is incorrect in a domain context) - cli_write needs to return ssize_t not size_t, because total can be -1 if the write fails. - fixed signed / unsigned warnings (how come i don't get those any more when i compile with gcc???) - nt password change added in smbd. yes, jeremy, i verified that the SMBtrans2 version still works. (This used to be commit fcfb40d2b0fc565ee4f66b3a3761c246366a2ef3) --- source3/libsmb/clientgen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7c58a969e7..d3233f59fd 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1195,7 +1195,6 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1395,7 +1394,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 0x0004 use raw named pipe protocol 0x0008 start of message mode named pipe protocol ****************************************************************************/ -size_t cli_write(struct cli_state *cli, +ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size) { -- cgit From fb556e14f3b47d5a1f465589084e8b30d84af8ca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Oct 1998 08:08:05 +0000 Subject: volker was concerned about unique inode numbers and smbsh. This set of changes uses the unique index number from a SMB_QUERY_FILE_ALL_INFO to try to provide inode numbers. If it is 0 then use the hash of the filename as before. (This used to be commit 2565ccf9de9d5e80fdb5bcadbc7130faba386d95) --- source3/libsmb/clientgen.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d3233f59fd..6a0818d177 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1669,7 +1669,8 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint32 *mode) + time_t *w_time, size_t *size, uint32 *mode, + SMB_INO_T *ino) { int data_len = 0; int param_len = 0; @@ -1721,6 +1722,9 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, if (mode) { *mode = IVAL(rdata, 32); } + if (ino) { + *ino = IVAL(rdata, 64); + } if (rdata) free(rdata); if (rparam) free(rparam); @@ -1733,7 +1737,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint32 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino) { int data_len = 0; int param_len = 0; @@ -1745,7 +1750,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, memset(param, 0, param_len); SSVAL(param, 0, fnum); - SSVAL(param, 2, SMB_INFO_STANDARD); + SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, /* name, length */ @@ -1768,19 +1773,25 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, } if (c_time) { - *c_time = make_unix_date2(rdata+0); + *c_time = interpret_long_date(rdata+0) - cli->serverzone; } if (a_time) { - *a_time = make_unix_date2(rdata+4); + *a_time = interpret_long_date(rdata+8) - cli->serverzone; } if (m_time) { - *m_time = make_unix_date2(rdata+8); + *m_time = interpret_long_date(rdata+16) - cli->serverzone; + } + if (w_time) { + *w_time = interpret_long_date(rdata+24) - cli->serverzone; } if (size) { - *size = IVAL(rdata, 12); + *size = IVAL(rdata, 40); } if (mode) { - *mode = SVAL(rdata,l1_attrFile); + *mode = IVAL(rdata, 32); + } + if (ino) { + *ino = IVAL(rdata, 64); } if (rdata) free(rdata); -- cgit From 4f2a6adb7cfee8de2c336cf926e29b720a1a8a47 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Oct 1998 03:31:00 +0000 Subject: added a couple more error codes to cli_error() (This used to be commit b2a7f85d597d4d2a71fd38d76aac0464d53df626) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6a0818d177..1e2869c0b8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2440,11 +2440,17 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRnoaccess: return EACCES; case ERRfilexists: return EEXIST; case ERRrename: return EEXIST; + case ERRbadshare: return EBUSY; + case ERRlock: return EBUSY; } } if (rcls == ERRSRV) { switch (code) { case ERRbadpw: return EPERM; + case ERRaccess: return EACCES; + case ERRnoresource: return ENOMEM; + case ERRinvdevice: return ENODEV; + case ERRinvnetname: return ENODEV; } } /* for other cases */ -- cgit From 099dae54dc944a6e0ec11c93e3004b2f097ea84d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 5 Nov 1998 12:42:16 +0000 Subject: don't bother trying QFILEINFO/QUERY_FILE_ALL_INFO with win95 as it totally screws it up, giving garbage for the size fields. (This used to be commit 86f98e0607e8a05ec026b919cc974c1c934b6882) --- source3/libsmb/clientgen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1e2869c0b8..7168d9cd92 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1746,6 +1746,10 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, pstring param; char *rparam=NULL, *rdata=NULL; + /* if its a win95 server then fail this - win95 totally screws it + up */ + if (cli->win95) return False; + param_len = 4; memset(param, 0, param_len); @@ -1768,7 +1772,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return False; } - if (!rdata || data_len < 22) { + if (!rdata || data_len < 68) { return False; } -- cgit From 8c62b28e0ef1e012ebb0713701916d82ffc7661e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 9 Nov 1998 03:45:49 +0000 Subject: converted smbclient to use clientgen.c rather than clientutil.c I did this when I saw yet another bug report complaining about smbclient intermittently missing files. Rather than applying more patches to smbclient it was better to move to the more robust clientgen.c code. The conversion wasn't perfect, I probably lost some features of smbclient while doing it, but at least smbclient should be consistent now. It if fails it should _always_ fail rather than giving people the false impression of a reliable utility. the tar stuff seems to work, but hasn't had much testing as I never use it myself. I'm sure someone will find bugs in my conversion of smbtar.c. It was quite tricky as it did a lot of its own SMB calls. It now uses clientgen.c exclusively. smbclient is still quite messy, but at least it doesn't build its own SMB packets. I haven't touched smbmount as I never use it. Mike, do you want to convert smbmount to use clientgen.c? (This used to be commit e14ca7765ace1b721dad8eca4a527a4e4a8f1ab8) --- source3/libsmb/clientgen.c | 234 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 199 insertions(+), 35 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7168d9cd92..650b9a27a3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -28,6 +28,14 @@ extern int DEBUGLEVEL; +/**************************************************************************** +recv an smb +****************************************************************************/ +static BOOL cli_receive_smb(struct cli_state *cli) +{ + return client_receive_smb(cli->fd,cli->inbuf,cli->timeout); +} + /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ @@ -256,7 +264,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout) || + if (!cli_receive_smb(cli) || CVAL(cli->inbuf,smb_rcls) != 0) { return(False); } @@ -317,7 +325,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, *data_len = *param_len = 0; - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -371,7 +379,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (total_data <= *data_len && total_param <= *param_len) break; - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -752,7 +760,7 @@ BOOL cli_session_setup(struct cli_state *cli, } cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -783,7 +791,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; return CVAL(cli->inbuf,smb_rcls) == 0; @@ -836,7 +844,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; if (CVAL(cli->inbuf,smb_rcls) != 0) { @@ -877,7 +885,7 @@ BOOL cli_tdis(struct cli_state *cli) cli_setup_packet(cli); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; return CVAL(cli->inbuf,smb_rcls) == 0; @@ -909,7 +917,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) pstrcpy(p,fname_dst); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -943,7 +951,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) pstrcpy(p,fname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -975,7 +983,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) pstrcpy(p,dname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1007,7 +1015,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) pstrcpy(p,dname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1052,7 +1060,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) p = skip_string(p,1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return -1; } @@ -1075,7 +1083,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) /* you must open for RW not just write - otherwise getattrE doesn't work! */ - if ((flags & O_ACCMODE) == O_WRONLY) { + if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) { flags = (flags & ~O_ACCMODE) | O_RDWR; } @@ -1123,7 +1131,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = skip_string(p,1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return -1; } @@ -1155,7 +1163,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SIVALS(cli->outbuf,smb_vwv1,-1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1199,7 +1207,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { cli->timeout = saved_timeout; return False; } @@ -1242,7 +1250,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 6, len); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1305,7 +1313,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t issued++; } - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return total; } @@ -1341,7 +1349,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t } while (received < issued) { - client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + cli_receive_smb(cli); received++; } @@ -1395,8 +1403,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 0x0008 start of message mode named pipe protocol ****************************************************************************/ ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size) + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size) { int total = -1; int issued=0; @@ -1420,7 +1428,7 @@ ssize_t cli_write(struct cli_state *cli, issued++; } - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return total; } @@ -1446,7 +1454,7 @@ ssize_t cli_write(struct cli_state *cli, } while (received < issued) { - client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + cli_receive_smb(cli); received++; } @@ -1473,7 +1481,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1527,7 +1535,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, pstrcpy(p+1, fname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1578,7 +1586,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) *p = 4; cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1914,7 +1922,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *)) +int cli_list(struct cli_state *cli,const char *Mask,int attribute, + void (*fn)(file_info *, const char *)) { int max_matches = 512; /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -2065,7 +2074,7 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info for (p=dirlist,i=0;ioutbuf),0) = 2; cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -2284,7 +2293,7 @@ retry: cli_send_smb(cli); DEBUG(5,("Sent session request\n")); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; #ifdef WITH_SSL @@ -2336,14 +2345,18 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) /**************************************************************************** initialise a client structure ****************************************************************************/ -BOOL cli_initialise(struct cli_state *cli) +struct cli_state *cli_initialise(struct cli_state *cli) { - if (cli->initialised) - { + if (!cli) { + cli = (struct cli_state *)malloc(sizeof(*cli)); + if (!cli) return NULL; + } + + if (cli->initialised) { cli_shutdown(cli); } - memset(cli, 0, sizeof(*cli)); + ZERO_STRUCTP(cli); cli->fd = -1; cli->cnum = -1; @@ -2363,7 +2376,7 @@ BOOL cli_initialise(struct cli_state *cli) cli->initialised = 1; - return True; + return cli; } /**************************************************************************** @@ -2773,3 +2786,154 @@ int cli_print_queue(struct cli_state *cli, return i; } + +/**************************************************************************** +check for existance of a dir +****************************************************************************/ +BOOL cli_chkpath(struct cli_state *cli, char *path) +{ + fstring path2; + char *p; + + fstrcpy(path2,path); + trim_string(path2,NULL,"\\"); + if (!*path2) *path2 = '\\'; + + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,4 + strlen(path2),True); + SCVAL(cli->outbuf,smb_com,SMBchkpth); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + fstrcpy(p,path2); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + return True; +} + + +/**************************************************************************** +start a message sequence +****************************************************************************/ +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp) +{ + char *p; + + /* send a SMBsendstrt command */ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBsendstrt; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,username); + p = skip_string(p,1); + *p++ = 4; + pstrcpy(p,host); + p = skip_string(p,1); + + set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + *grp = SVAL(cli->inbuf,smb_vwv0); + + return True; +} + + +/**************************************************************************** +send a message +****************************************************************************/ +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +{ + char *p; + + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,1,len+3,True); + CVAL(cli->outbuf,smb_com) = SMBsendtxt; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,grp); + + p = smb_buf(cli->outbuf); + *p = 1; + SSVAL(p,1,len); + memcpy(p+3,msg,len); + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + return True; +} + +/**************************************************************************** +end a message +****************************************************************************/ +BOOL cli_message_end(struct cli_state *cli, int grp) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,1,0,True); + CVAL(cli->outbuf,smb_com) = SMBsendend; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + + SSVAL(cli->outbuf,smb_vwv0,grp); + + cli_setup_packet(cli); + + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + return True; +} + + +/**************************************************************************** +query disk space +****************************************************************************/ +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBdskattr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); + *total = SVAL(cli->inbuf,smb_vwv0); + *avail = SVAL(cli->inbuf,smb_vwv3); + + return True; +} -- cgit From e4f974c611c179a5e7827ec8325e01811db6540b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Nov 1998 20:33:37 +0000 Subject: Makefile.in: Removed rpc_server/srv_ldap_helpers.c per J.F.'s instructions. client/client.c: client/clitar.c: include/client.h: smbwrapper/smbw_dir.c: smbwrapper/smbw_stat.c: smbwrapper/smbw.c: lib/util.c: Converted all use of 'mode' to uint16. smbd/quotas.c: Fixed stupid comment bug I put in there :-(. printing/printing.c: Fix from J.F. to new code. Jeremy. (This used to be commit bacd3e9d2036a804e73644a28fc498f229c8446c) --- source3/libsmb/clientgen.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 650b9a27a3..fc4c7f1d5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1466,7 +1466,7 @@ ssize_t cli_write(struct cli_state *cli, do a SMBgetattrE call ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint32 *attr, size_t *size, + uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { bzero(cli->outbuf,smb_size); @@ -1517,7 +1517,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, do a SMBgetatr call ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, char *fname, - uint32 *attr, size_t *size, time_t *t) + uint16 *attr, size_t *size, time_t *t) { char *p; @@ -1563,7 +1563,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, /**************************************************************************** do a SMBsetatr call ****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) { char *p; @@ -1602,7 +1602,7 @@ send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint32 *mode) + size_t *size, uint16 *mode) { int data_len = 0; int param_len = 0; @@ -1677,7 +1677,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint32 *mode, + time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) { int data_len = 0; @@ -1724,12 +1724,12 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, if (w_time) { *w_time = interpret_long_date(rdata+24) - cli->serverzone; } + if (mode) { + *mode = SVAL(rdata, 32); + } if (size) { *size = IVAL(rdata, 40); } - if (mode) { - *mode = IVAL(rdata, 32); - } if (ino) { *ino = IVAL(rdata, 64); } @@ -1744,7 +1744,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint32 *mode, size_t *size, + uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { @@ -1796,12 +1796,12 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, if (w_time) { *w_time = interpret_long_date(rdata+24) - cli->serverzone; } + if (mode) { + *mode = SVAL(rdata, 32); + } if (size) { *size = IVAL(rdata, 40); } - if (mode) { - *mode = IVAL(rdata, 32); - } if (ino) { *ino = IVAL(rdata, 64); } @@ -1922,7 +1922,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,int attribute, +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *)) { int max_matches = 512; -- cgit From d85dcf86d59c14cb624bbb69b658fc6aba842593 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Nov 1998 06:12:19 +0000 Subject: largely rewrote smbpasswd so that the code is understandable. This should allow us to call a function in swat rather than piping to smbpasswd. while doing this I also fixed quite a few "const char *" versus "char *" issues that cropped up while using const to track down bugs in the code. This led to changes in several generic functions. The smbpasswd changes should be correct but they have not been extensively tested. At least if I have introduced bugs then we should be able to fix them more easily than before. (This used to be commit 713864dd0322ae2ae2d83e333d85be35a7eed4ec) --- source3/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc4c7f1d5d..b4ca7a1d77 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2087,8 +2087,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, Send a SamOEMChangePassword command ****************************************************************************/ -BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password, - char *old_password) +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password) { char param[16+sizeof(fstring)]; char data[532]; @@ -2317,7 +2317,7 @@ retry: /**************************************************************************** open the client sockets ****************************************************************************/ -BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern struct in_addr ipzero; -- cgit From d30b6ab54847164aa3add34f3b50132af58f9453 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 12 Nov 1998 22:17:51 +0000 Subject: .cvsignore: Removed old entries. client/client.c: include/client.h: Added some debug messages that the old client used to generate. These are needed to make scripts such as 'findsmb' work - there may be other changes to keep backwards output compatibility. Do we need a -old-client-compat argument ? libsmb/clientgen.c: Fixed crash bug where malloc'ed data wasn't being cleared - corrupted malloc chains. web/swat.c: John's changes to get rid of "ghost" table entries. (This used to be commit 3c45a3503ea57d17e98eb3e57514161a5c82e45e) --- source3/libsmb/clientgen.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b4ca7a1d77..4eaebfa6ed 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -772,6 +772,20 @@ BOOL cli_session_setup(struct cli_state *cli, /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); + if (cli->protocol >= PROTOCOL_NT1) { + /* + * Save off some of the connected server + * info. + */ + char *server_domain,*server_os,*server_type; + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + fstrcpy(cli->server_os, server_os); + fstrcpy(cli->server_type, server_type); + fstrcpy(cli->server_domain, server_domain); + } + fstrcpy(cli->user_name, user); return True; @@ -2349,7 +2363,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) { if (!cli) { cli = (struct cli_state *)malloc(sizeof(*cli)); - if (!cli) return NULL; + if (!cli) + return NULL; + ZERO_STRUCTP(cli); } if (cli->initialised) { -- cgit From 24ca89bfb03fb82e975eff94070275ee403cd0f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 14 Nov 1998 01:04:13 +0000 Subject: Removed acconfig.h configure configure.in include/config.h.in: Made smbwrapper not made by default. nmbd*: Changed all calls to namestr() to nmbd_namestr() to fix broken FreeBSD include file problem...sigh. Jeremy. (This used to be commit 9ee8f39aed8772a05c203161b4ae6b7d90d67481) --- source3/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4eaebfa6ed..81f75d2cb2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2541,7 +2541,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) fstrcpy(dest_host, cli->full_dest_host_name); DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - namestr(&calling), namestr(&called), + nmb_namestr(&calling), nmb_namestr(&called), inet_ntoa(cli->dest_ip), cli->user_name, cli->domain)); @@ -2571,7 +2571,7 @@ BOOL cli_establish_connection(struct cli_state *cli, BOOL do_shutdown, BOOL do_tcon) { DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - namestr(calling), namestr(called), inet_ntoa(*dest_ip), + nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), cli->user_name, cli->domain)); /* establish connection */ @@ -2586,7 +2586,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - namestr(calling), inet_ntoa(*dest_ip))); + nmb_namestr(calling), inet_ntoa(*dest_ip))); return False; } } -- cgit From 3ba68d045c4f1f2c6dea014d11189cbabc3e0eb1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 14 Nov 1998 04:16:07 +0000 Subject: automatically uppercase server and share names (win95 won't handle lowercase share names!) (This used to be commit dddf1d8522707b828cac466c4a9ab2807d098573) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81f75d2cb2..550f7cc391 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -839,6 +839,7 @@ BOOL cli_send_tconX(struct cli_state *cli, slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); + strupper(fullshare); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); -- cgit From 74d539f5573a3ed3ff1b96c54752a389da4c3e14 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 17 Nov 1998 16:19:04 +0000 Subject: - group database API. oops and oh dear, the threat has been carried out: the pre-alpha "domain group" etc parameters have disappeared. - interactive debug detection - re-added mem_man (andrew's memory management, detects memory corruption) - american spellings of "initialise" replaced with english spelling of "initialise". - started on "lookup_name()" and "lookup_sid()" functions. proper ones. - moved lots of functions around. created some modules of commonly used code. e.g the password file locking code, which is used in groupfile.c and aliasfile.c and smbpass.c - moved RID_TYPE_MASK up another bit. this is really unfortunate, but there is no other "fast" way to identify users from groups from aliases. i do not believe that this code saves us anything (the multipliers) and puts us at a disadvantage (reduces the useable rid space). the designers of NT aren't silly: if they can get away with a user- interface-speed LsaLookupNames / LsaLookupSids, then so can we. i spoke with isaac at the cifs conference, the only time for example that they do a security context check is on file create. certainly not on individual file reads / writes, which would drastically hit their performance and ours, too. - renamed myworkgroup to global_sam_name, amongst other things, when used in the rpc code. there is also a global_member_name, as we are always responsible for a SAM database, the scope of which is limited by the role of the machine (e.g if a member of a workgroup, your SAM is for _local_ logins only, and its name is the name of your server. you even still have a SID. see LsaQueryInfoPolicy, levels 3 and 5). - updated functionality of groupname.c to be able to cope with names like DOMAIN\group and SERVER\alias. used this code to be able to do aliases as well as groups. this code may actually be better off being used in username mapping, too. - created a connect to serverlist function in clientgen.c and used it in password.c - initialisation in server.c depends on the role of the server. well, it does now. - rpctorture. smbtorture. EXERCISE EXTREME CAUTION. (This used to be commit 0d21e1e6090b933f396c764af535ca3388a562db) --- source3/libsmb/clientgen.c | 199 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 150 insertions(+), 49 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 550f7cc391..bb792b7e2b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -39,18 +39,27 @@ static BOOL cli_receive_smb(struct cli_state *cli) /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli) +static BOOL cli_send_smb(struct cli_state *cli, BOOL show) { size_t len; size_t nwritten=0; ssize_t ret; BOOL reestablished=False; + if (show) + { + show_msg(cli->outbuf); + } + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) { + if (ret <= 0 && errno == EPIPE && !reestablished) + { + DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n", + strerror(errno))); + if (cli_reestablish_connection(cli)) { reestablished = True; nwritten=0; @@ -60,8 +69,7 @@ static BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", len,ret)); - close_sockets(); - exit(1); + return False; } nwritten += ret; } @@ -259,8 +267,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -300,8 +307,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); tot_data += this_ldata; tot_param += this_lparam; @@ -328,8 +334,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; - show_msg(cli->inbuf); - /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -382,8 +386,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; - show_msg(cli->inbuf); - /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -759,11 +761,12 @@ BOOL cli_session_setup(struct cli_state *cli, set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) + { + DEBUG(10,("cli_session_setup: receive smb failed\n")); return False; - - show_msg(cli->inbuf); + } if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; @@ -804,7 +807,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -858,7 +861,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -899,7 +902,7 @@ BOOL cli_tdis(struct cli_state *cli) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -931,7 +934,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) *p++ = 4; pstrcpy(p,fname_dst); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -965,7 +968,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) *p++ = 4; pstrcpy(p,fname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -997,7 +1000,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1029,7 +1032,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1074,7 +1077,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -1145,7 +1148,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -1177,7 +1180,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1218,7 +1221,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); + cli_send_smb(cli, True); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1264,7 +1267,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1300,7 +1303,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli); + cli_send_smb(cli, True); } /**************************************************************************** @@ -1406,8 +1409,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); } /**************************************************************************** @@ -1495,7 +1497,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1549,7 +1551,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, *p = 4; pstrcpy(p+1, fname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1600,7 +1602,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = skip_string(p,1); *p = 4; - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -2163,13 +2165,14 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; - if (cli_send_trans(cli,SMBtrans, + if (!cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ data,data_len,0 /* data, length, max */ - ) == False) { + )) + { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; @@ -2223,11 +2226,11 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) + { return False; - - show_msg(cli->inbuf); + } if (CVAL(cli->inbuf,smb_rcls) != 0 || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { @@ -2305,7 +2308,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli); + cli_send_smb(cli, False); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) @@ -2401,6 +2404,7 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { + DEBUG(10,("cli_shutdown\n")); if (cli->outbuf) { free(cli->outbuf); @@ -2414,7 +2418,9 @@ void cli_shutdown(struct cli_state *cli) sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ if (cli->fd != -1) - close(cli->fd); + { + close(cli->fd); + } memset(cli, 0, sizeof(*cli)); } @@ -2429,10 +2435,18 @@ void cli_shutdown(struct cli_state *cli) ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); + int flgs2; char rcls; int code; + if (!cli->initialised) + { + DEBUG(0,("cli_error: client state uninitialised!\n")); + return EINVAL; + } + + flgs2 = SVAL(cli->inbuf,smb_flg2); + if (eclass) *eclass = 0; if (num ) *num = 0; @@ -2671,7 +2685,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session setup\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2682,19 +2698,104 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } } } if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return True; } +/**************************************************************************** + connect to one of multiple servers: don't care which +****************************************************************************/ +BOOL cli_connect_serverlist(struct cli_state *cli, char *p) +{ + extern pstring global_myname; + extern pstring scope; + fstring remote_machine; + struct in_addr dest_ip; + struct nmb_name calling, called; + BOOL connected_ok = True; + + ZERO_STRUCT(cli); + + if (!cli_initialise(cli)) + { + DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + return False; + } + + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) + { + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if (!resolve_name( remote_machine, &dest_ip, 0x20)) + { + DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); + continue; + } + + if (ismyip(dest_ip)) + { + DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); + continue; + } + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + pwd_set_nullpwd(&cli->pwd); + + if (!cli_establish_connection(cli, remote_machine, &dest_ip, + &calling, &called, + "IPC$", "IPC", + False, True)) + { + cli_shutdown(cli); + continue; + } + + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + + connected_ok = True; + break; + } + + if (!connected_ok) + { + DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); + cli_shutdown(cli); + } + + return connected_ok; +} + /**************************************************************************** cancel a print job ****************************************************************************/ @@ -2826,7 +2927,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) *p++ = 4; fstrcpy(p,path2); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -2862,7 +2963,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2895,7 +2996,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) *p = 1; SSVAL(p,1,len); memcpy(p+3,msg,len); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2920,7 +3021,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp) cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2943,7 +3044,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } -- cgit From b70700dba2f82d64f85bea51841081b0e4b6f9e9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 26 Nov 1998 06:35:25 +0000 Subject: Replaced ZERO_STRUCT() with ZERO_STRUCTP() in cli_connect_serverlist(). Fix by Matt Chapman (This used to be commit c44b418d6fd16a257af21f6b5b29b1cdf26015b7) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bb792b7e2b..d20ecfa1d9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2727,7 +2727,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) struct nmb_name calling, called; BOOL connected_ok = True; - ZERO_STRUCT(cli); + ZERO_STRUCTP(cli); if (!cli_initialise(cli)) { -- cgit From 7f63a310624c4a30a12a5dac0f94e68102491e6e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 30 Nov 1998 15:32:15 +0000 Subject: andrej spotted problem with connect_serverlist (starts off assuming a connection succeeds...). (This used to be commit c0efc35b27d50c40bc04bfd9fb1d61ea5d32bde5) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d20ecfa1d9..fc0df84d4a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2725,7 +2725,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) fstring remote_machine; struct in_addr dest_ip; struct nmb_name calling, called; - BOOL connected_ok = True; + BOOL connected_ok = False; ZERO_STRUCTP(cli); -- cgit From b31c5281461fa42d277be7403d860feae96f2a9f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 30 Nov 1998 16:00:27 +0000 Subject: another attempt at a fix on connect_serverlist()... (This used to be commit 603c5f6df8c525f30d00da912d408b98378ea538) --- source3/libsmb/clientgen.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc0df84d4a..5f6408bad1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2727,14 +2727,6 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) struct nmb_name calling, called; BOOL connected_ok = False; - ZERO_STRUCTP(cli); - - if (!cli_initialise(cli)) - { - DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); - return False; - } - /* * Treat each name in the 'password server =' line as a potential * PDC/BDC. Contact each in turn and try and authenticate. @@ -2742,6 +2734,14 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { + ZERO_STRUCTP(cli); + + if (!cli_initialise(cli)) + { + DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + return False; + } + standard_sub_basic(remote_machine); strupper(remote_machine); -- cgit From 90ce7b9288f23cbf0fe3ce2aecb0b11d283ed531 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 2 Dec 1998 20:03:08 +0000 Subject: ERRmoredata is an acceptable error code, it is not an error. (This used to be commit 9bce7340d60a49594f67cc3c6cc6119b33a5358a) --- source3/libsmb/clientgen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5f6408bad1..99d868e216 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -328,6 +328,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; + uint8 eclass; + uint32 num; *data_len = *param_len = 0; @@ -342,7 +344,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, return(False); } - if (cli_error(cli, NULL, NULL)) + /* DOS error "more data" is an acceptable error code */ + if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) { return(False); } @@ -393,7 +396,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli, NULL, NULL)) + /* DOS error "more data" is an acceptable error code */ + if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) { return(False); } -- cgit From e67a8d9d984dbdef307294358d7d9a7f4314ea09 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 14 Dec 1998 21:22:59 +0000 Subject: server_cryptkey() now calling cli_connectserverlist(). stupid microsoft idiotic *SMBSERVER connectionism added to cli_connect_serverlist(). also added check for protocol < LANMAN2. (This used to be commit c2bcb3a286f22ed4f0f55da2a3eb2bff17906fb1) --- source3/libsmb/clientgen.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 99d868e216..5bae8ffa81 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2728,7 +2728,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) extern pstring scope; fstring remote_machine; struct in_addr dest_ip; - struct nmb_name calling, called; + struct nmb_name calling, called, stupid_smbserver_called; BOOL connected_ok = False; /* @@ -2763,19 +2763,28 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) make_nmb_name(&calling, global_myname , 0x0 , scope); make_nmb_name(&called , remote_machine, 0x20, scope); + /* stupid microsoft destruction of the ability of netbios + * to provide multiple netbios servers on one host. + */ + make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope); pwd_set_nullpwd(&cli->pwd); if (!cli_establish_connection(cli, remote_machine, &dest_ip, &calling, &called, "IPC$", "IPC", + False, True) && + !cli_establish_connection(cli, remote_machine, &dest_ip, + &calling, &stupid_smbserver_called, + "IPC$", "IPC", False, True)) { cli_shutdown(cli); continue; } - if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + if (cli->protocol < PROTOCOL_LANMAN2 || + !IS_BITS_SET_ALL(cli->sec_mode, 1)) { DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", remote_machine)); -- cgit From 2cc786548b4460525ce2e0bf09209eee48a5ea08 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 15 Jan 1999 05:09:36 +0000 Subject: eclass != ERRDOS && num != ERRmoredata is not the same as !(eclass == ERRDOS && num == ERRmoredata) This was causing smbclient to segfault on receiving certain errors. (This used to be commit 15bd172530af360cf16ad626330dfe2ea92100df) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5bae8ffa81..688764fa73 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -345,7 +345,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, } /* DOS error "more data" is an acceptable error code */ - if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) + if (cli_error(cli, &eclass, &num) && !(eclass == ERRDOS && num == ERRmoredata)) { return(False); } -- cgit From b4e34006e88308aa0f315648992a15501399cf10 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Mon, 18 Jan 1999 01:35:43 +0000 Subject: In security=user mode we must allow cli_connect_serverlist to connect to our own smbd process, rather than complaining about a password server loop. (This used to be commit 63d7822b9d87d085194de6895d3e271cedcd3c9a) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 688764fa73..e269011402 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2755,7 +2755,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) continue; } - if (ismyip(dest_ip)) + if ((lp_security() != SEC_USER) && (ismyip(dest_ip))) { DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); continue; -- cgit From f5f913b001ab66c2266e3325f8c91af2486116a2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 25 Jan 1999 01:46:14 +0000 Subject: Putting back the -p flag in smbclient. However, it seems that the -s flag in smbclient is also ignored :-( (This used to be commit f6c78192664d611d4663ed7459a2789315861eec) --- source3/libsmb/clientgen.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e269011402..a1a5bbf0a9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -27,6 +27,19 @@ extern int DEBUGLEVEL; +/* + * set the port that will be used for connections by the client + */ + +int cli_set_port(struct cli_state *cli, int port) +{ + + if (port != 0) + cli -> port = port; + + return cli -> port; /* return it incase caller wants it */ + +} /**************************************************************************** recv an smb @@ -2355,8 +2368,10 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } + if (cli -> port == 0) cli -> port = 139; + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - 139, cli->timeout); + cli -> port, cli->timeout); if (cli->fd == -1) return False; @@ -2382,6 +2397,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) ZERO_STRUCTP(cli); + cli -> port = 0; cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)getpid(); -- cgit From 4af8d7aa2925569d55f33b2844882089c5569691 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 27 Jan 1999 00:08:33 +0000 Subject: - got client code cleartext passwords working again in cli_session_setup. needed this for some tests. - removed code that said "if lm password is not encrypted then encrypt both lm and nt passwords". actually it said "if lm password length is not 24 bytes and we're in security=user mode..." it didn't bother to check whether the nt password was NULL or not, and doing the encryption inside cli_session_setup is the wrong place. - checked all instances where cli_session_setup is called with cleartext passwords that are expected to then be encrypted (see above) with the test "if pwlen != 24...". there was only one: all the others either provide encrypted passwords, do null sessions or use cli_establish_connection. * recommendation: use cli_establish_connection() in smbwrapper/smbw.c (This used to be commit 2a509e9606f8aefbefa6e7b49878726464dbed44) --- source3/libsmb/clientgen.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a1a5bbf0a9..428f8e237f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -696,36 +696,42 @@ BOOL cli_session_setup(struct cli_state *cli, fstring pword, ntpword; if (cli->protocol < PROTOCOL_LANMAN1) + { return True; + } - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) + { return False; } - if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { - /* Null session connect. */ - pword[0] = '\0'; - ntpword[0] = '\0'; - } else { - if ((cli->sec_mode & 2) && passlen != 24) { - passlen = 24; - ntpasslen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); - } else { - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } - - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + /* if in share level security then don't send a password now */ fstrcpy(pword, ""); passlen=1; fstrcpy(ntpword, ""); ntpasslen=1; } + else if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) + { + /* Null session connect. */ + pword[0] = '\0'; + ntpword[0] = '\0'; + } + else if (passlen == 24 && ntpasslen == 24) + { + /* encrypted password send, implicit from 24-byte lengths */ + memcpy(pword, pass, 24); + memcpy(ntpword, ntpass, 24); + } + else + { + /* plain-text password send */ + fstrcpy(pword, pass); + fstrcpy(ntpword, ""); + ntpasslen = 0; + } /* send a session setup command */ bzero(cli->outbuf,smb_size); -- cgit From deb61cb44b846951fe2c3343fd1b92510be9a9f0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 28 Jan 1999 18:40:53 +0000 Subject: returned cli_session_setup to previous behaviour. added a couple of validation checks and also added capability to send plaintext passwords. send "ntpasslen" of zero to do this. sending same plaintext password for pass and ntpass arguments will result in previous behaviour of encrypting password if server supports it. (This used to be commit 17f4c5a785cf20901bcb76510e5ea9b0a6928115) --- source3/libsmb/clientgen.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 428f8e237f..a43731ffcc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -713,25 +713,40 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(ntpword, ""); ntpasslen=1; } - else if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) + else if ((passlen == 0 || passlen == 1) && (pass[0] == '\0')) { /* Null session connect. */ - pword[0] = '\0'; + pword [0] = '\0'; ntpword[0] = '\0'; } else if (passlen == 24 && ntpasslen == 24) { - /* encrypted password send, implicit from 24-byte lengths */ - memcpy(pword, pass, 24); - memcpy(ntpword, ntpass, 24); + if (IS_BITS_SET_ALL(cli->sec_mode, 2)) + { + /* encrypted password, implicit from 24-byte lengths */ + memcpy(pword , pass , 24); + memcpy(ntpword, ntpass, 24); + } + else + { + DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); + return False; + } } - else + else if (ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) { - /* plain-text password send */ + /* plain-text password: server doesn't support encrypted. */ fstrcpy(pword, pass); fstrcpy(ntpword, ""); ntpasslen = 0; } + else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ + { + /* plain-text password requesting to be encrypted */ + uchar *key = (uchar *)cli->cryptkey; + SMBencrypt ((uchar *)pass , key,(uchar *)pword ); + SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); + } /* send a session setup command */ bzero(cli->outbuf,smb_size); -- cgit From 1cf9521b2de9a6053c658329d54fe178be94de19 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Mon, 1 Feb 1999 05:25:54 +0000 Subject: Must set password length to 24 after we encrypt a password. (This used to be commit af83778abc5fae0df53ed1874181e33bc8de8d94) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a43731ffcc..d40c95b9c1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -746,6 +746,8 @@ BOOL cli_session_setup(struct cli_state *cli, uchar *key = (uchar *)cli->cryptkey; SMBencrypt ((uchar *)pass , key,(uchar *)pword ); SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); + passlen = 24; + ntpasslen = 24; } /* send a session setup command */ -- cgit From c6d16eea4394ff1c4d12cb435eebb0686b5ee736 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 11 Feb 1999 18:50:13 +0000 Subject: the UNICODE issue... (This used to be commit 73db80f34183324845407b00f58462ff2d7b47ea) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d40c95b9c1..60498c8fb2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -226,7 +226,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter, /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, int trans, +BOOL cli_send_trans(struct cli_state *cli, int trans, char *name, int pipe_name_len, int fid, int flags, uint16 *setup, int lsetup, int msetup, -- cgit From 236cea4efa18094c3445bee310195ac12b6073ee Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 1 Mar 1999 16:31:14 +0000 Subject: Benjamin Kuit's MYSQL SAM Database implementation. Copyright (C) Benjamin Kuit 1999. (This used to be commit fdf61e1dabc2c977ee5cf1e9d60e3380f19840da) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 60498c8fb2..e188cb3b99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -679,6 +679,8 @@ prots[] = {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, +#if 0 +#endif {-1,NULL} }; -- cgit From 99020c9b090449e3113acc2ceb667cb41a63a6b8 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Tue, 23 Mar 1999 14:58:26 +0000 Subject: ERRmoredata is informational and should not be treated as a hard error anywhere. (This used to be commit 71b861f7468d7950bedb61dd18a4b9d830bf8628) --- source3/libsmb/clientgen.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e188cb3b99..bd5d58e4de 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -341,8 +341,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; - uint8 eclass; - uint32 num; *data_len = *param_len = 0; @@ -357,8 +355,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, return(False); } - /* DOS error "more data" is an acceptable error code */ - if (cli_error(cli, &eclass, &num) && !(eclass == ERRDOS && num == ERRmoredata)) + if (cli_error(cli, NULL, NULL)) { return(False); } @@ -409,8 +406,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - /* DOS error "more data" is an acceptable error code */ - if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) + + if (cli_error(cli, NULL, NULL)) { return(False); } @@ -1381,7 +1378,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t mid = SVAL(cli->inbuf, smb_mid) - cli->mid; size2 = SVAL(cli->inbuf, smb_vwv5); - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_error(cli, NULL, NULL)) + { blocks = MIN(blocks, mid-1); continue; } @@ -2535,6 +2533,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRrename: return EEXIST; case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; + case ERRmoredata: return 0; /* Informational only */ } } if (rcls == ERRSRV) { -- cgit From cae3620b2e8abbe35f0369a82d5461cb596475a3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 24 Jun 1999 18:58:08 +0000 Subject: safe string error reporting functions (found a potential buffer overflow of a pstrcpy into an fstring). (This used to be commit ac0060443de800fec9042b69b299ff2e9128a31c) --- source3/libsmb/clientgen.c | 97 ++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 46 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bd5d58e4de..cb0f2e5c74 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -90,6 +90,26 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) return True; } +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) +{ + static fstring error_message; + cli_safe_errstr(cli, error_message, sizeof(error_message)); + return error_message; +} + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len) +{ + smb_safe_errstr(cli->inbuf, msg, len); +} + /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -112,24 +132,32 @@ struct }; /**************************************************************************** - return a description of an SMB error + return a description of a RAP error ****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) +BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen) { - return smb_errstr(cli->inbuf); + int i; + + slprintf(err_msg, msglen - 1, "RAP code %d", rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) + { + if (rap_errmap[i].err == rap_error) + { + safe_strcpy( err_msg, rap_errmap[i].message, msglen); + return True; + } + } + return False; } -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen) { - static fstring error_message; uint8 errclass; uint32 errnum; - int i; /* * Errors are of three kinds - smb errors, @@ -142,47 +170,24 @@ char *cli_errstr(struct cli_state *cli) if (errclass != 0) { - return cli_smb_errstr(cli); + cli_safe_smb_errstr(cli, err_msg, msglen); } - - /* - * Was it an NT error ? - */ - - if (cli->nt_error) + else if (cli->nt_error) { - char *nt_msg = get_nt_error_msg(cli->nt_error); - - if (nt_msg == NULL) - { - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); - } - else - { - fstrcpy(error_message, nt_msg); - } + /* + * Was it an NT error ? + */ - return error_message; + (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen); } - - /* - * Must have been a rap error. - */ - - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); - - for (i = 0; rap_errmap[i].message != NULL; i++) + else { - if (rap_errmap[i].err == cli->rap_error) - { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; + /* + * Must have been a rap error. + */ + (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen); + } } - /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ -- cgit From 1dc6c6c7ca54578d9e6040a9d4d5e509f1ad3af3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 24 Jun 1999 19:09:03 +0000 Subject: use nmb_safe_namestr. (This used to be commit de9a38b0bcb5adcb6e502f2200d3e84bdcbdfc48) --- source3/libsmb/clientgen.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cb0f2e5c74..4f73b6e51b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2634,8 +2634,14 @@ BOOL cli_establish_connection(struct cli_state *cli, char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) { + fstring callingstr; + fstring calledstr; + + nmb_safe_namestr(calling, callingstr, sizeof(callingstr)); + nmb_safe_namestr(called , calledstr , sizeof(calledstr )); + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), + callingstr, calledstr, inet_ntoa(*dest_ip), cli->user_name, cli->domain)); /* establish connection */ @@ -2650,7 +2656,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(calling), inet_ntoa(*dest_ip))); + callingstr, inet_ntoa(*dest_ip))); return False; } } @@ -2763,7 +2769,6 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } - /**************************************************************************** connect to one of multiple servers: don't care which ****************************************************************************/ -- 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/libsmb/clientgen.c | 259 +++++++++++++++++++++++++++++++-------------- 1 file changed, 182 insertions(+), 77 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4f73b6e51b..8d3508d98f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,7 +2,8 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client generic functions - Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Tridgell 1994-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-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 @@ -690,70 +691,25 @@ prots[] = /**************************************************************************** send a session setup ****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) +BOOL cli_session_setup_x(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *user_domain) { char *p; - fstring pword, ntpword; + +#ifdef DEBUG_PASSWORD + DEBUG(100,("cli_session_setup. pass, ntpass\n")); + dump_data(100, pass, passlen); + dump_data(100, ntpass, ntpasslen); +#endif if (cli->protocol < PROTOCOL_LANMAN1) { return True; } - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) - { - return False; - } - - if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - /* if in share level security then don't send a password now */ - fstrcpy(pword, ""); - passlen=1; - fstrcpy(ntpword, ""); - ntpasslen=1; - } - else if ((passlen == 0 || passlen == 1) && (pass[0] == '\0')) - { - /* Null session connect. */ - pword [0] = '\0'; - ntpword[0] = '\0'; - } - else if (passlen == 24 && ntpasslen == 24) - { - if (IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* encrypted password, implicit from 24-byte lengths */ - memcpy(pword , pass , 24); - memcpy(ntpword, ntpass, 24); - } - else - { - DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); - return False; - } - } - else if (ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* plain-text password: server doesn't support encrypted. */ - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ - { - /* plain-text password requesting to be encrypted */ - uchar *key = (uchar *)cli->cryptkey; - SMBencrypt ((uchar *)pass , key,(uchar *)pword ); - SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); - passlen = 24; - ntpasslen = 24; - } - /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -770,7 +726,7 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); + memcpy(p,pass,passlen); p += passlen; pstrcpy(p,user); strupper(p); @@ -790,17 +746,17 @@ BOOL cli_session_setup(struct cli_state *cli, SSVAL(cli->outbuf,smb_vwv8,ntpasslen); SSVAL(cli->outbuf,smb_vwv11,0); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); + memcpy(p,pass,passlen); p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpword,ntpasslen); + memcpy(p,ntpass,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); pstrcpy(p,user); strupper(p); p = skip_string(p,1); - pstrcpy(p,workgroup); - strupper(p); + pstrcpy(p,user_domain); p = skip_string(p,1); pstrcpy(p,"Unix");p = skip_string(p,1); + CVAL(p, 0) = 0; p++; pstrcpy(p,"Samba");p = skip_string(p,1); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } @@ -833,11 +789,127 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(cli->server_domain, server_domain); } - fstrcpy(cli->user_name, user); - return True; } +static BOOL cli_calc_session_pwds(struct cli_state *cli, + char *pword, char *ntpword, + char *pass, int *passlen, + char *ntpass, int *ntpasslen, + BOOL ntlmv2) +{ +#ifdef DEBUG_PASSWORD + DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n")); + dump_data(100, pass, *passlen); + dump_data(100, ntpass, *ntpasslen); +#endif + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + /* if in share level security then don't send a password now */ + fstrcpy(pword, ""); + *passlen=1; + fstrcpy(ntpword, ""); + *ntpasslen=1; + } + else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0')) + { + /* Null session connect. */ + pword [0] = '\0'; + ntpword[0] = '\0'; + } + else if (*passlen == 24 && *ntpasslen >= 24) + { + if (IS_BITS_SET_ALL(cli->sec_mode, 2)) + { + /* encrypted password, implicit from 24-byte lengths */ + memcpy(pword , pass , *passlen); + memcpy(ntpword, ntpass, *ntpasslen); + } + else + { + DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); + return False; + } + } + else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) + { + /* plain-text password: server doesn't support encrypted. */ + fstrcpy(pword, pass); + fstrcpy(ntpword, ""); + *ntpasslen = 0; + } + else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ + { + if (ntlmv2) + { + /* plain-text password requesting to be encrypted */ + uchar *srv_key = (uchar *)cli->cryptkey; + uchar nt_owf[16]; + uchar kr[16]; + + SMBgenclientchals(cli->lm_cli_chal, + cli->nt_cli_chal, + &cli->nt_cli_chal_len, + cli->calling.name, + cli->domain); + + nt_owf_gen(pword, nt_owf); + ntv2_owf_gen(nt_owf, cli->user_name, cli->domain, kr); + + /* lm # */ + memcpy(pword, cli->lm_cli_chal, 8); + SMBOWFencrypt_ntv2(kr, + srv_key, 8, + cli->lm_cli_chal, 8, + &pword[8]); + *passlen = 24; + + /* nt # */ + memcpy(ntpword, cli->lm_cli_chal, cli->nt_cli_chal_len); + SMBOWFencrypt_ntv2(kr, + srv_key, 8, + cli->nt_cli_chal, cli->nt_cli_chal_len, + &ntpword[cli->nt_cli_chal_len]); + *ntpasslen = cli->nt_cli_chal_len + 16; + } + else + { + /* plain-text password requesting to be encrypted */ + uchar *key = (uchar *)cli->cryptkey; + SMBencrypt ((uchar *)pass , key,(uchar *)pword ); + SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); + *passlen = 24; + *ntpasslen = 24; + } + } + return True; +} + +/**************************************************************************** +send a session setup +****************************************************************************/ +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *user_domain) +{ + fstring pword, ntpword; + + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) + { + return False; + } + + fstrcpy(cli->user_name, user); + + return cli_calc_session_pwds(cli, pword, ntpword, + pass, &passlen, + ntpass, &ntpasslen, cli->use_ntlmv2) && + cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen, + user_domain); +} + /**************************************************************************** Send a uloggoff. *****************************************************************************/ @@ -2614,9 +2686,12 @@ BOOL cli_reestablish_connection(struct cli_state *cli) if (cli_establish_connection(cli, dest_host, &cli->dest_ip, &calling, &called, - share, dev, False, do_tcon)) { - if (cli->fd != oldfd) { - if (dup2(cli->fd, oldfd) == oldfd) { + share, dev, False, do_tcon)) + { + if (cli->fd != oldfd) + { + if (dup2(cli->fd, oldfd) == oldfd) + { close(cli->fd); } } @@ -2640,9 +2715,10 @@ BOOL cli_establish_connection(struct cli_state *cli, nmb_safe_namestr(calling, callingstr, sizeof(callingstr)); nmb_safe_namestr(called , calledstr , sizeof(calledstr )); - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n", callingstr, calledstr, inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); + cli->user_name, cli->domain, + cli->use_ntlmv2 ? "v2" : "v1")); /* establish connection */ @@ -2665,7 +2741,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session request\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2673,7 +2751,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed negprot\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2725,20 +2805,45 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; unsigned char lm_sess_pwd[24]; + unsigned char nt_sess_pwd[128]; + size_t nt_sess_pwd_len; + extern pstring global_myname; + + if (cli->use_ntlmv2 != False) + { + DEBUG(10,("cli_establish_connection: NTLMv2\n")); + pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, + cli->user_name, global_myname, cli->domain); + } + else + { + DEBUG(10,("cli_establish_connection: NTLMv1\n")); + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + } - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd, + &nt_sess_pwd_len); /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->user_name, (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), + (char*)nt_sess_pwd, nt_sess_pwd_len, cli->domain)) { DEBUG(1,("failed session setup\n")); + + if (cli->use_ntlmv2 == Auto) + { + DEBUG(10,("NTLMv2 failed. Using NTLMv1\n")); + cli->use_ntlmv2 = False; + return cli_establish_connection(cli, + dest_host, dest_ip, + calling, called, + service, service_type, + do_shutdown, do_tcon); + } + if (do_shutdown) { cli_shutdown(cli); -- cgit From 8e145947988d4ac8d025dcd876fae14c75db9527 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 19:39:23 +0000 Subject: smbclient modified to use cli_establish_connection(). smbclient therefore now uses improved authentication. smbclient now "broken" for "scripts" based on DEBUG() output. cli_establish_connection() requires modification to support old scripts. (This used to be commit b0539d43407cb2b0bab7977908de09b21b145218) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d3508d98f..cc51ab0c4b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -754,6 +754,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, strupper(p); p = skip_string(p,1); pstrcpy(p,user_domain); + strupper(p); p = skip_string(p,1); pstrcpy(p,"Unix");p = skip_string(p,1); CVAL(p, 0) = 0; p++; @@ -2851,6 +2852,16 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + DEBUG(1,("session setup ok\n")); + + if (*cli->server_domain || *cli->server_os || *cli->server_type) + { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + cli->server_domain, + cli->server_os, + cli->server_type)); + } + if (do_tcon) { if (!cli_send_tconX(cli, service, service_type, -- cgit From 820c38221126392955eb221c72aa02189fa91c7e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 8 Jul 1999 19:44:06 +0000 Subject: fixed problem with NULL ntpasswd parameters causing crash in static cli_calc_session_pwds(). this code used to be inside cli_session_setup() itself and worked on non-NULL local variables. (This used to be commit 7aff19ba57fd91572da7cbe16f118d11226590e3) --- source3/libsmb/clientgen.c | 52 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cc51ab0c4b..78c09d53e9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -765,7 +765,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { - DEBUG(10,("cli_session_setup: receive smb failed\n")); + DEBUG(10,("cli_session_setup_x: receive smb failed\n")); return False; } @@ -799,26 +799,59 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, char *ntpass, int *ntpasslen, BOOL ntlmv2) { + BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL; + + if (pass == NULL || passlen == NULL) + { + DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n")); + return False; + } + if ((ntpass != NULL || ntpasslen != NULL) && + (ntpass == NULL || ntpasslen == NULL)) + { + DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n")); + return False; + } + #ifdef DEBUG_PASSWORD DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n")); dump_data(100, pass, *passlen); - dump_data(100, ntpass, *ntpasslen); + if (ntpass_ok) + { + dump_data(100, ntpass, *ntpasslen); + } #endif if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) { /* if in share level security then don't send a password now */ - fstrcpy(pword, ""); + pword[0] = '\0'; *passlen=1; - fstrcpy(ntpword, ""); - *ntpasslen=1; + if (ntpass_ok) + { + ntpword[0] = '\0'; + *ntpasslen=1; + } + return True; } else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0')) { /* Null session connect. */ pword [0] = '\0'; - ntpword[0] = '\0'; + if (ntpass_ok) + { + ntpword[0] = '\0'; + *ntpasslen=1; + } + + return True; } - else if (*passlen == 24 && *ntpasslen >= 24) + + if (!ntpass_ok) + { + return False; + } + + if (*passlen == 24 && *ntpasslen >= 24) { if (IS_BITS_SET_ALL(cli->sec_mode, 2)) { @@ -828,7 +861,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, } else { - DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); + DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n")); return False; } } @@ -839,8 +872,9 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, fstrcpy(ntpword, ""); *ntpasslen = 0; } - else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ + else if (ntpasslen != NULL) { + /* passlen != 0, ntpasslen != 0 && server supports encryption */ if (ntlmv2) { /* plain-text password requesting to be encrypted */ -- cgit From 6919a92aee585d1d64b89ec359d038e5a6fa9b7e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 9 Jul 1999 03:55:15 +0000 Subject: When making anonymous connections, must pass pointers to real nt password and password length variables not constants. (This used to be commit 236022071f2f6df0c583fd88d9802d9b3ea6f73e) --- source3/libsmb/clientgen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 78c09d53e9..2d19473feb 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2794,14 +2794,14 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { - fstring passwd; - int pass_len; + fstring passwd, ntpasswd; + int pass_len, ntpass_len; if (cli->pwd.null_pwd) { /* attempt null session */ - passwd[0] = 0; - pass_len = 1; + passwd[0] = ntpasswd[0] = 0; + pass_len = ntpass_len = 1; } else { @@ -2813,7 +2813,7 @@ BOOL cli_establish_connection(struct cli_state *cli, /* attempt clear-text session */ if (!cli_session_setup(cli, cli->user_name, passwd, pass_len, - NULL, 0, + ntpasswd, ntpass_len, cli->domain)) { DEBUG(1,("failed session setup\n")); -- cgit From 50429f60566839faf647cd4c36b66903c7b855ab Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 11 Jul 1999 19:26:27 +0000 Subject: anon passwd connection: passlen=1; ntpasslen=0. (This used to be commit 12ee037d44a603ce50982d5b90e08c30339de750) --- source3/libsmb/clientgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2d19473feb..beb73e736b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -840,7 +840,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, if (ntpass_ok) { ntpword[0] = '\0'; - *ntpasslen=1; + *ntpasslen=0; } return True; @@ -2403,7 +2403,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & 1) { + if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; cli->writebraw_supported = True; } @@ -2550,6 +2550,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) } cli->initialised = 1; + cli->capabilities = CAP_DFS; return cli; } @@ -2795,7 +2796,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { fstring passwd, ntpasswd; - int pass_len, ntpass_len; + int pass_len = 0, ntpass_len = 0; if (cli->pwd.null_pwd) { -- cgit From 80d714e75b48b6ed75de48ea0ca878736eb9b259 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 3 Aug 1999 17:21:34 +0000 Subject: close socket issues: - ssl close from cli_reestablish_connection() not called. - ntlmv2 fall-back to ntlmv1 failed. (This used to be commit fdc275353de85fde0c348320e4d64ba66365b73b) --- source3/libsmb/clientgen.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index beb73e736b..765160ffe4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2555,6 +2555,24 @@ struct cli_state *cli_initialise(struct cli_state *cli) return cli; } +/**************************************************************************** +close the socket descriptor +****************************************************************************/ +void cli_close_socket(struct cli_state *cli) +{ +#ifdef WITH_SSL + if (cli->fd != -1) + { + sslutil_disconnect(cli->fd); + } +#endif /* WITH_SSL */ + if (cli->fd != -1) + { + close(cli->fd); + } + cli->fd = -1; +} + /**************************************************************************** shutdown a client structure ****************************************************************************/ @@ -2569,14 +2587,7 @@ void cli_shutdown(struct cli_state *cli) { free(cli->inbuf); } -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ - if (cli->fd != -1) - { - close(cli->fd); - } + cli_close_socket(cli); memset(cli, 0, sizeof(*cli)); } @@ -2702,15 +2713,19 @@ BOOL cli_reestablish_connection(struct cli_state *cli) /* copy the parameters necessary to re-establish the connection */ if (cli->cnum != 0) + { + do_tcon = True; + } + + if (do_tcon) { fstrcpy(share, cli->share); fstrcpy(dev , cli->dev); - do_tcon = True; } memcpy(&called , &(cli->called ), sizeof(called )); memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->full_dest_host_name); + fstrcpy(dest_host, cli->desthost); DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", nmb_namestr(&calling), nmb_namestr(&called), @@ -2728,7 +2743,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) { if (dup2(cli->fd, oldfd) == oldfd) { - close(cli->fd); + cli_close_socket(cli); } } return True; @@ -2873,6 +2888,13 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(10,("NTLMv2 failed. Using NTLMv1\n")); cli->use_ntlmv2 = False; + if (do_tcon) + { + fstrcpy(cli->share, service); + fstrcpy(cli->dev, service_type); + } + fstrcpy(cli->desthost, dest_host); + cli_close_socket(cli); return cli_establish_connection(cli, dest_host, dest_ip, calling, called, -- cgit From ebfa9fa928c7efc2313deb576373da7c536a2aad Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 3 Aug 1999 17:43:12 +0000 Subject: attempting a connection to port 445 first, followed by a connection to 139 if this fails. (This used to be commit 5f821e65015c27f5306c3a707841cd0228509974) --- source3/libsmb/clientgen.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 765160ffe4..1913ccd79b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -36,9 +36,9 @@ int cli_set_port(struct cli_state *cli, int port) { if (port != 0) - cli -> port = port; + cli->port = port; - return cli -> port; /* return it incase caller wants it */ + return cli->port; /* return it incase caller wants it */ } @@ -2442,6 +2442,11 @@ BOOL cli_session_request(struct cli_state *cli, memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); + if (cli->port == 445) + { + return True; + } + /* put in the destination name */ p = cli->outbuf+len; name_mangle(cli->called .name, p, cli->called .name_type); @@ -2490,6 +2495,7 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern struct in_addr ipzero; + int port = cli->port; fstrcpy(cli->desthost, host); @@ -2503,12 +2509,23 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } - if (cli -> port == 0) cli -> port = 139; + if (port == 0) port = 445; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli -> port, cli->timeout); + port, cli->timeout); if (cli->fd == -1) - return False; + { + if (cli->port != 0) + { + return False; + } + port = 139; + + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + port, cli->timeout); + if (cli->fd == -1) return False; + } + return True; } @@ -2532,7 +2549,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) ZERO_STRUCTP(cli); - cli -> port = 0; + cli->port = 0; cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)getpid(); -- cgit From 9c593512155a4e1d9eb01ac63d4458df59b7357d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 3 Aug 1999 18:03:08 +0000 Subject: bug-fix in connection to port 445. cool! it works! (This used to be commit 062b9302c1c7a21df74571ead5f89ce002820d53) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1913ccd79b..ecab198c94 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2526,6 +2526,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (cli->fd == -1) return False; } + cli->port = port; return True; } -- cgit From f221bfa4ace27b898c9326b1d81df59e0ceba032 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 18 Aug 1999 20:10:12 +0000 Subject: debug info display (netbios layer). (This used to be commit 5c974cc4a4cdcb9fd3fe01e93aa577b81cf2d18b) --- source3/libsmb/clientgen.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ecab198c94..efed3555ba 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -60,13 +60,21 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) ssize_t ret; BOOL reestablished=False; + len = smb_len(cli->outbuf) + 4; + if (show) { - show_msg(cli->outbuf); + uint8 msg_type = CVAL(cli->outbuf, 0); + if (msg_type == 0) + { + show_msg(cli->outbuf); + } + else + { + dump_data(10, cli->outbuf, len); + } } - len = smb_len(cli->outbuf) + 4; - while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0 && errno == EPIPE && !reestablished) @@ -2465,7 +2473,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli, False); + cli_send_smb(cli, True); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) -- cgit From b9b4c1d56349824616f2fcaff57cedbc52168059 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 15 Sep 1999 17:30:02 +0000 Subject: #defines for port 445 to SMB_PORT2 (This used to be commit a8d4560e0064a67a234eae89a564b79d2426d9a9) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index efed3555ba..3e31b980c4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2517,7 +2517,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } - if (port == 0) port = 445; + if (port == 0) port = SMB_PORT2; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); @@ -2527,7 +2527,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { return False; } - port = 139; + port = SMB_PORT; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); -- cgit From 701f9ed2c97ad50a4258e278a3674b8f5a747d8e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 16 Sep 1999 22:46:45 +0000 Subject: reading in smb server domain name from SMBnegprot response (This used to be commit 25025f450531c66c0fd9f7eed886cb288d76d025) --- source3/libsmb/clientgen.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3e31b980c4..6d704dc144 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2400,7 +2400,10 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol >= PROTOCOL_NT1) { + if (cli->protocol >= PROTOCOL_NT1) + { + char *buf = smb_buf(cli->inbuf); + int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct))); /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); @@ -2409,13 +2412,26 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + memcpy(cli->cryptkey, buf,8); + if (bcc > 8) + { + unibuf_to_ascii(cli->server_domain, buf+8, + sizeof(cli->server_domain)); + } + else + { + cli->server_domain[0] = 0; + } cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; cli->writebraw_supported = True; } - } else if (cli->protocol >= PROTOCOL_LANMAN1) { + DEBUG(5,("server's domain: %s bcc: %d\n", + cli->server_domain, bcc)); + } + else if (cli->protocol >= PROTOCOL_LANMAN1) + { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); @@ -2834,6 +2850,12 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + if (cli->domain[0] == 0) + { + safe_strcpy(cli->domain, cli->server_domain, + sizeof(cli->domain)); + } + if (cli->pwd.cleartext || cli->pwd.null_pwd) { fstring passwd, ntpasswd; @@ -2885,13 +2907,12 @@ BOOL cli_establish_connection(struct cli_state *cli, unsigned char lm_sess_pwd[24]; unsigned char nt_sess_pwd[128]; size_t nt_sess_pwd_len; - extern pstring global_myname; if (cli->use_ntlmv2 != False) { DEBUG(10,("cli_establish_connection: NTLMv2\n")); pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, - cli->user_name, global_myname, cli->domain); + cli->user_name, calling->name, cli->domain); } else { -- cgit From cba7662da1fd9ed8bd9f9969417adf1fe5f0d33b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 7 Oct 1999 22:10:29 +0000 Subject: - added rudimentary CAP_UNICODE support because i thought it was part of a problem i was having. - added rudimentary CAP_STATUS32 support for same reason. - added hard-coded, copy-the-same-data-from-over-the-wire version of CAP_EXTENDED_SECURITY, which is a security-blob to encapsulate GSSAPI which encodes SPNEGO which is used to negotiate Kerberos or NTLMSSP. i have implemented NTLMSSP which negotiates NTLMv1 or NTLMv2 and 40-bit or 128-bit etc. i have implemented NTLMv1 / 40-bit. *whew*. (This used to be commit e5b80bd2f76fda70e41e4a9007eb035dab92ed8e) --- source3/libsmb/clientgen.c | 466 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 396 insertions(+), 70 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6d704dc144..8db5bd6e00 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -42,6 +42,56 @@ int cli_set_port(struct cli_state *cli, int port) } +/**************************************************************************** +copy a string (unicode or otherwise) into an SMB buffer. skips a string +plus points to next +****************************************************************************/ +static char *cli_put_string(struct cli_state *cli, char *p, const char *str, + BOOL skip_end) +{ + uint16 flgs2 = SVAL(cli->outbuf, smb_flg2); + if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) + { + p = align2(p, cli->outbuf); + p = ascii_to_unibuf(p, str, 1024); + if (skip_end) + { + CVAL(p, 0) = 0; p++; + CVAL(p, 0) = 0; p++; + } + return p; + } + else + { + pstrcpy(p, str); + p = skip_string(p, 1); + if (skip_end) + { + CVAL(p, 0) = 0; p++; + } + return p; + } +} + +/**************************************************************************** +copy a string (unicode or otherwise) into an SMB buffer. skips a string +plus points to next +****************************************************************************/ +static const char *cli_get_string(struct cli_state *cli, const char *p, + char *str, size_t str_len) +{ + uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); + if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) + { + return unibuf_to_ascii(str, p, str_len); + } + else + { + safe_strcpy(str, p, str_len-1); + return skip_string(p, 1); + } +} + /**************************************************************************** recv an smb ****************************************************************************/ @@ -202,14 +252,24 @@ setup basics in a outgoing packet ****************************************************************************/ static void cli_setup_packet(struct cli_state *cli) { + uint16 flgs2 = 0; + flgs2 |= FLAGS2_LONG_PATH_COMPONENTS; + flgs2 |= FLAGS2_32_BIT_ERROR_CODES; +#if 0 + flgs2 |= FLAGS2_UNICODE_STRINGS; +#endif + flgs2 |= FLAGS2_EXT_SEC; + cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); - if (cli->protocol > PROTOCOL_CORE) { + + if (cli->protocol > PROTOCOL_CORE) + { SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,0x1); + SSVAL(cli->outbuf,smb_flg2,flgs2); } } @@ -705,7 +765,13 @@ BOOL cli_session_setup_x(struct cli_state *cli, char *ntpass, int ntpasslen, char *user_domain) { + uint8 eclass; + uint32 ecode; char *p; + BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; + + DEBUG(100,("cli_session_setup. extended security: %s\n", + BOOLSTR(esec))); #ifdef DEBUG_PASSWORD DEBUG(100,("cli_session_setup. pass, ntpass\n")); @@ -739,7 +805,31 @@ BOOL cli_session_setup_x(struct cli_state *cli, pstrcpy(p,user); strupper(p); } - else + else if (esec) + { + set_message(cli->outbuf,12,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE); + p = smb_buf(cli->outbuf); + memcpy(p,pass,passlen); + p += passlen; + + p = cli_put_string(cli, p, "Unix", False); + p = cli_put_string(cli, p, "Samba", False); + p = cli_put_string(cli, p, "", False); + p++; + + set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + } + else { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; @@ -758,44 +848,65 @@ BOOL cli_session_setup_x(struct cli_state *cli, p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpass,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,user_domain); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - CVAL(p, 0) = 0; p++; - pstrcpy(p,"Samba");p = skip_string(p,1); + strupper(user); + p = cli_put_string(cli, p, user, False); + strupper(user_domain); + p = cli_put_string(cli, p, user_domain, False); + p = cli_put_string(cli, p, "Unix", True); + p = cli_put_string(cli, p, "Samba", False); + set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli, True); - if (!cli_receive_smb(cli)) + cli_send_smb(cli, True); + if (!cli_receive_smb(cli)) { DEBUG(10,("cli_session_setup_x: receive smb failed\n")); return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli, &eclass, &ecode)) + { + uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); + if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES)) + { + if (ecode != ERRmoredata || !esec) + { + return False; + } + } + else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */ + { + return False; + } + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - fstrcpy(cli->server_type, server_type); - fstrcpy(cli->server_domain, server_domain); + if (cli->protocol >= PROTOCOL_NT1) + { + if (esec) + { + } + else + { + /* + * Save off some of the connected server + * info. + */ + char *server_domain; + char *server_os; + char *server_type; + + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + + fstrcpy(cli->server_os, server_os); + fstrcpy(cli->server_type, server_type); + fstrcpy(cli->server_domain, server_domain); + } } return True; @@ -1003,8 +1114,7 @@ BOOL cli_send_tconX(struct cli_state *cli, "\\\\%s\\%s", cli->desthost, share); strupper(fullshare); - set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); + set_message(cli->outbuf,4, 0, True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -1014,9 +1124,11 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); + p = cli_put_string(cli, p, fullshare, False); + fstrcpy(p, dev); + p = skip_string(p, 1); + + set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False); SCVAL(cli->inbuf,smb_rcls, 1); @@ -1030,8 +1142,10 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); - if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); + if (cli->protocol >= PROTOCOL_NT1) + { + cli_get_string(cli, smb_buf(cli->inbuf), + cli->dev, sizeof(cli->dev)); } if (strcasecmp(share,"IPC$")==0) { @@ -1039,8 +1153,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && - smb_buflen(cli->inbuf) == 3) { + if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) + { /* almost certainly win95 - enable bug fixes */ cli->win95 = True; } @@ -1304,8 +1418,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - p = skip_string(p,1); + p = cli_put_string(cli, p, fname, False); + + set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False); cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { @@ -2412,23 +2527,37 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey, buf,8); - if (bcc > 8) + + cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); + if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE)) { - unibuf_to_ascii(cli->server_domain, buf+8, - sizeof(cli->server_domain)); + cli->readbraw_supported = True; + cli->writebraw_supported = True; } - else + + if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) { + /* oops, some kerberos-related nonsense. */ + /* expect to have to use NTLMSSP-over-SMB */ + DEBUG(10,("unknown kerberos-related (?) blob\n")); + memset(cli->cryptkey, 0, 8); cli->server_domain[0] = 0; } - cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & CAP_RAW_MODE) { - cli->readbraw_supported = True; - cli->writebraw_supported = True; + else + { + memcpy(cli->cryptkey, buf,8); + if (bcc > 8) + { + unibuf_to_ascii(cli->server_domain, buf+8, + sizeof(cli->server_domain)); + } + else + { + cli->server_domain[0] = 0; + } + DEBUG(5,("server's domain: %s bcc: %d\n", + cli->server_domain, bcc)); } - DEBUG(5,("server's domain: %s bcc: %d\n", - cli->server_domain, bcc)); } else if (cli->protocol >= PROTOCOL_LANMAN1) { @@ -2659,24 +2788,26 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (eclass) *eclass = 0; if (num ) *num = 0; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { /* 32 bit error codes detected */ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + switch (nt_err & 0xFFFFFF) + { + case NT_STATUS_ACCESS_VIOLATION : return EACCES; + case NT_STATUS_NO_SUCH_FILE : return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE : return ENODEV; + case NT_STATUS_INVALID_HANDLE : return EBADF; + case NT_STATUS_NO_MEMORY : return ENOMEM; + case NT_STATUS_ACCESS_DENIED : return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION : return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID : return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; } /* for all other cases - a default code */ @@ -2856,7 +2987,202 @@ BOOL cli_establish_connection(struct cli_state *cli, sizeof(cli->domain)); } - if (cli->pwd.cleartext || cli->pwd.null_pwd) + if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) + { + /* common to both session setups */ + char pwd_buf[128]; + int buf_len; + char *p; + char *e = pwd_buf + sizeof(pwd_buf); + + /* 1st session setup */ + char pwd_data[34] = + { + 0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e, + 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22, + 0x04, 0x20 + }; + /* 2nd session setup */ +#if 0 + char pwd_data_2[8] = + { + 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b + }; +#endif + char pwd_data_2[8] = + { + 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b + }; + prs_struct auth_resp; + int resp_len; + char *p_gssapi; + char *p_oem; + char *p_gssapi_end; + uint16 gssapi_len; + + memset(pwd_buf, 0, sizeof(pwd_buf)); + memcpy(pwd_buf, pwd_data, sizeof(pwd_data)); + p = pwd_buf + sizeof(pwd_data); + + safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); + p = skip_string(p, 1); + CVAL(p, 0) = 0x1; + p += 4; + if (cli->ntlmssp_cli_flgs == 0) + { + cli->ntlmssp_cli_flgs = + NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_OEM | + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_SEAL | + NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | + NTLMSSP_NEGOTIATE_00001000 | + NTLMSSP_NEGOTIATE_00002000; +#if 0 + cli->ntlmssp_cli_flgs = 0x80008207; +#endif + } + SIVAL(p, 0, cli->ntlmssp_cli_flgs); + p += 4; + p += 16; /* skip some NULL space */ + CVAL(p, 0) = 0; p++; /* alignment */ + + buf_len = PTR_DIFF(p, pwd_buf); + + /* first session negotiation stage */ + if (!cli_session_setup_x(cli, cli->user_name, + pwd_buf, buf_len, + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + + DEBUG(1,("1st session setup ok\n")); + + if (*cli->server_domain || *cli->server_os || *cli->server_type) + { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + cli->server_domain, + cli->server_os, + cli->server_type)); + } + + p = smb_buf(cli->inbuf) + 0x2f; + cli->ntlmssp_cli_flgs = IVAL(p, 0); /* 0x80808a05; */ + p += 4; + memcpy(cli->cryptkey, p, 8); +#ifdef DEBUG_PASSWORD + DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n", + cli->ntlmssp_cli_flgs)); + + DEBUG(100,("cli_session_setup_x: crypt key\n")); + dump_data(100, cli->cryptkey, 8); +#endif + prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); + + pwd_make_lm_nt_owf(&cli->pwd, cli->cryptkey); + + create_ntlmssp_resp(&cli->pwd, cli->domain, + cli->user_name, cli->calling.name, + cli->ntlmssp_cli_flgs, + &auth_resp); + prs_link(NULL, &auth_resp, NULL); + + memset(pwd_buf, 0, sizeof(pwd_buf)); + p = pwd_buf; + + CVAL(p, 0) = 0xa1; p++; + CVAL(p, 0) = 0x82; p++; + p_gssapi = p; p+= 2; + CVAL(p, 0) = 0x30; p++; + CVAL(p, 0) = 0x82; p++; + p += 2; + + CVAL(p, 0) = 0xa2; p++; + CVAL(p, 0) = 0x82; p++; + p_oem = p; p+= 2; + CVAL(p, 0) = 0x04; p++; + CVAL(p, 0) = 0x82; p++; + p += 2; + + p_gssapi_end = p; + + safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); + p = skip_string(p, 1); + CVAL(p, 0) = 0x3; + p += 4; + + resp_len = mem_buf_len(auth_resp.data); + mem_buf_copy(p, auth_resp.data, 0, resp_len); + prs_mem_free(&auth_resp); + + p += resp_len; + + buf_len = PTR_DIFF(p, pwd_buf); + gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12; + + *p_gssapi++ = (gssapi_len >> 8) & 0xff; + *p_gssapi++ = gssapi_len & 0xff; + + p_gssapi += 2; + gssapi_len -= 4; + + *p_gssapi++ = (gssapi_len >> 8) & 0xff; + *p_gssapi++ = gssapi_len & 0xff; + + gssapi_len -= 4; + + *p_oem++ = (gssapi_len >> 8) & 0xff; + *p_oem++ = gssapi_len & 0xff; + + p_oem += 2; + gssapi_len -= 4; + + *p_oem++ = (gssapi_len >> 8) & 0xff; + *p_oem++ = gssapi_len & 0xff; + + /* second session negotiation stage */ + if (!cli_session_setup_x(cli, cli->user_name, + pwd_buf, buf_len, + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + + DEBUG(1,("2nd session setup ok\n")); + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + NULL, 0)) + + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + } + } + else if (cli->pwd.cleartext || cli->pwd.null_pwd) { fstring passwd, ntpasswd; int pass_len = 0, ntpass_len = 0; @@ -2925,9 +3251,9 @@ BOOL cli_establish_connection(struct cli_state *cli, /* attempt encrypted session */ if (!cli_session_setup_x(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, nt_sess_pwd_len, - cli->domain)) + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + (char*)nt_sess_pwd, nt_sess_pwd_len, + cli->domain)) { DEBUG(1,("failed session setup\n")); -- cgit From 81711b9c5aec21bfe94cbde3349268a89dac53c6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 14 Oct 1999 19:45:52 +0000 Subject: const issues (This used to be commit 858f79b362dce8aa06013533209bc982cb99d33d) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8db5bd6e00..f50cd19c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -77,7 +77,7 @@ static char *cli_put_string(struct cli_state *cli, char *p, const char *str, copy a string (unicode or otherwise) into an SMB buffer. skips a string plus points to next ****************************************************************************/ -static const char *cli_get_string(struct cli_state *cli, const char *p, +static const char *cli_get_string(struct cli_state *cli, char *p, char *str, size_t str_len) { uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); -- cgit From 87d92a1f1182a6b4e4dbe91d7f574c7ac8aecb21 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 19 Oct 1999 19:55:43 +0000 Subject: need status codes from cli_net_req_chal() and cli_net_auth2(). this format is what i would like _all_ these functions to be (returning status codes, not BOOL) but that's a horrendous amount of work at the moment :) (This used to be commit 02f240604241367f146b26934ad1a1b2563430de) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f50cd19c38..90ea3d12bf 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1596,7 +1596,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t if (size == 0) return 0; - while (received < blocks) { + while (received < blocks) + { int size2; while (issued - received < mpx && issued < blocks) { -- cgit From 8e1f542ddf97fef925a88e2c3d9c1e82fb2f6683 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 25 Oct 1999 16:22:08 +0000 Subject: one of those wonderful moments when running against a different MSRPC implementation (NT5) when you discover that your code is trash. samr_enum_dom_users(), samr_enum_dom_aliases() and samr_enum_dom_groups() all take a HANDLE for multiple-call enumeration purposes. (This used to be commit 19490d8b4fb8a103f3df4e6104f6f22937b0c518) --- source3/libsmb/clientgen.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 90ea3d12bf..d792eeeaa1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -255,10 +255,10 @@ static void cli_setup_packet(struct cli_state *cli) uint16 flgs2 = 0; flgs2 |= FLAGS2_LONG_PATH_COMPONENTS; flgs2 |= FLAGS2_32_BIT_ERROR_CODES; + flgs2 |= FLAGS2_EXT_SEC; #if 0 flgs2 |= FLAGS2_UNICODE_STRINGS; #endif - flgs2 |= FLAGS2_EXT_SEC; cli->rap_error = 0; cli->nt_error = 0; @@ -750,8 +750,6 @@ prots[] = {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, -#if 0 -#endif {-1,NULL} }; @@ -842,7 +840,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,0); + SIVAL(cli->outbuf,smb_vwv11, CAP_STATUS32); p = smb_buf(cli->outbuf); memcpy(p,pass,passlen); p += SVAL(cli->outbuf,smb_vwv7); @@ -3091,7 +3089,17 @@ BOOL cli_establish_connection(struct cli_state *cli, #endif prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); - pwd_make_lm_nt_owf(&cli->pwd, cli->cryptkey); + if (cli->use_ntlmv2 != False) + { + DEBUG(10,("cli_establish_connection: NTLMv2\n")); + pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, + cli->user_name, calling->name, cli->domain); + } + else + { + DEBUG(10,("cli_establish_connection: NTLMv1\n")); + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + } create_ntlmssp_resp(&cli->pwd, cli->domain, cli->user_name, cli->calling.name, -- cgit From 2adba4bfbbe360cd8c1eca1b90354fd63c503dd0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 25 Oct 1999 16:23:42 +0000 Subject: the new CAP_EXTENDED_SECURITY code needed to support NTLMv2. also removed switching on CAP_STATUS32 from non-CAP_EXTENDED_SECURITY code (enabled for test purposes only) (This used to be commit 96d8e14f50fda8047d209fa0b94b98a95ce51f21) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d792eeeaa1..4bffb5aa3e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -840,7 +840,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SIVAL(cli->outbuf,smb_vwv11, CAP_STATUS32); + SIVAL(cli->outbuf,smb_vwv11, 0); p = smb_buf(cli->outbuf); memcpy(p,pass,passlen); p += SVAL(cli->outbuf,smb_vwv7); -- cgit From 32dedee7f006351c505801dc207dbc46ca08044a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 5 Nov 1999 18:40:38 +0000 Subject: experimental spoolss rpcclient commands (This used to be commit c86edef90e7c96d5a99be29e2d2a3679ed26d97d) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4bffb5aa3e..b153654591 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -998,6 +998,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, uchar *srv_key = (uchar *)cli->cryptkey; uchar nt_owf[16]; uchar kr[16]; + HMACMD5Context ctx; SMBgenclientchals(cli->lm_cli_chal, cli->nt_cli_chal, @@ -1023,6 +1024,11 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, cli->nt_cli_chal, cli->nt_cli_chal_len, &ntpword[cli->nt_cli_chal_len]); *ntpasslen = cli->nt_cli_chal_len + 16; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, &ctx); + hmac_md5_final(cli->sess_key, &ctx); + } else { -- cgit From dab1a1227873f1a88dc7a4b8f63edcccd60ada85 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:24:01 +0000 Subject: you know what? this sort of thing makes me laugh. hmm, what functions have we got. and what data do we have. hmm.. i wonder what the NTLMv2 user session key can be... hmmm... weell.... there's some hidden data here, generated from the user password that doesn't go over-the-wire, so that's _got_ to be involved. and... that bit of data took a lot of computation to produce, so it's probably _also_ involved... and md4 no, md5? no, how about hmac_md5 yes let's try that one (the other's didn't work) oh goodie, it worked! i love it when this sort of thing happens. took all of fifteen minutes to guess it. tried concatenating client and server challenges. tried concatenating _random_ bits of client and server challenges. tried md5 of the above. tried hmac_md5 of the above. eventually, it boils down to this: kr = MD4(NT#,username,domainname) hmacntchal=hmac_md5(kr, nt server challenge) sess_key = hmac_md5(kr, hmacntchal); (This used to be commit ab174759cd210fe1be888d0c589a5b2669f7ff1e) --- source3/libsmb/clientgen.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b153654591..26a5f25c7d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1026,8 +1026,13 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, *ntpasslen = cli->nt_cli_chal_len + 16; hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, &ctx); + hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, + &ctx); hmac_md5_final(cli->sess_key, &ctx); +#if DEBUG_PASSWORD + DEBUG(100,("session key:\n")); + dump_data(100, cli->sess_key, sizeof(cli->sess_key)); +#endif } else @@ -3262,7 +3267,7 @@ BOOL cli_establish_connection(struct cli_state *cli, } pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd, - &nt_sess_pwd_len); + &nt_sess_pwd_len, cli->sess_key); /* attempt encrypted session */ if (!cli_session_setup_x(cli, cli->user_name, -- cgit From f8b82a7b9507e11595bc924def179dc1d7d79a54 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Nov 1999 20:24:33 +0000 Subject: first stages of removing struct cli_state* and uint16 fnum from all msrpc client code. the intent is to hide / abstract / associate connection info behind policy handles. this makes the msrpc functions look more and more like their nt equivalents. who-hou! (This used to be commit c01b18e632aede6fce7264ef6971d7ddba945cfb) --- source3/libsmb/clientgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 26a5f25c7d..61ce3f9900 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -25,7 +25,6 @@ #include "includes.h" #include "trans2.h" - extern int DEBUGLEVEL; /* @@ -1331,7 +1330,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) /**************************************************************************** open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname) +int cli_nt_create(struct cli_state *cli, const char *fname) { char *p; @@ -1375,7 +1374,8 @@ int cli_nt_create(struct cli_state *cli, char *fname) /**************************************************************************** open a file ****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +int cli_open(struct cli_state *cli, const char *fname, + int flags, int share_mode) { char *p; unsigned openfn=0; @@ -3684,3 +3684,4 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } + -- cgit From 2803a72751cf511aa0b5e6745e1b169faa66f68a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Nov 1999 22:45:09 +0000 Subject: ok. *whew*. this is the first completed part of the restructure. verified that lsaquery, lsalookupsids work, and found some bugs in the parameters of these commands :-) soo... we now have an lsa_* api that has the same arguments as the nt Lsa* api! cool! the only significant coding difference is the introduction of a user_credentials structure, containing user, domain, pass and ntlmssp flags. (This used to be commit 57bff6fe82d777e599d535f076efb2328ba1188b) --- source3/libsmb/clientgen.c | 77 ++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 30 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 61ce3f9900..94cd89e342 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,6 +31,14 @@ extern int DEBUGLEVEL; * set the port that will be used for connections by the client */ +void copy_user_creds(struct user_credentials *to, const struct user_credentials *from) +{ + safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1); + safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); + memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); + to->ntlmssp_flags = from->ntlmssp_flags; +}; + int cli_set_port(struct cli_state *cli, int port) { @@ -585,7 +593,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privilages = SVAL(p, 24); + cli->privileges = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); @@ -1003,10 +1011,10 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, cli->nt_cli_chal, &cli->nt_cli_chal_len, cli->calling.name, - cli->domain); + cli->usr.domain); nt_owf_gen(pword, nt_owf); - ntv2_owf_gen(nt_owf, cli->user_name, cli->domain, kr); + ntv2_owf_gen(nt_owf, cli->usr.user_name, cli->usr.domain, kr); /* lm # */ memcpy(pword, cli->lm_cli_chal, 8); @@ -1063,7 +1071,7 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - fstrcpy(cli->user_name, user); + fstrcpy(cli->usr.user_name, user); return cli_calc_session_pwds(cli, pword, ntpword, pass, &passlen, @@ -2695,6 +2703,15 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } +/**************************************************************************** +initialise a client structure +****************************************************************************/ +void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) +{ + copy_user_creds(&cli->usr, usr); + cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; +} + /**************************************************************************** initialise a client structure ****************************************************************************/ @@ -2913,7 +2930,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", nmb_namestr(&calling), nmb_namestr(&called), inet_ntoa(cli->dest_ip), - cli->user_name, cli->domain)); + cli->usr.user_name, cli->usr.domain)); cli->fd = -1; @@ -2951,7 +2968,7 @@ BOOL cli_establish_connection(struct cli_state *cli, DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n", callingstr, calledstr, inet_ntoa(*dest_ip), - cli->user_name, cli->domain, + cli->usr.user_name, cli->usr.domain, cli->use_ntlmv2 ? "v2" : "v1")); /* establish connection */ @@ -2991,10 +3008,10 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } - if (cli->domain[0] == 0) + if (cli->usr.domain[0] == 0) { - safe_strcpy(cli->domain, cli->server_domain, - sizeof(cli->domain)); + safe_strcpy(cli->usr.domain, cli->server_domain, + sizeof(cli->usr.domain)); } if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) @@ -3064,10 +3081,10 @@ BOOL cli_establish_connection(struct cli_state *cli, buf_len = PTR_DIFF(p, pwd_buf); /* first session negotiation stage */ - if (!cli_session_setup_x(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->usr.user_name, pwd_buf, buf_len, NULL, 0, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3103,17 +3120,17 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->use_ntlmv2 != False) { DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, - cli->user_name, calling->name, cli->domain); + pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, + cli->usr.user_name, calling->name, cli->usr.domain); } else { DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); } - create_ntlmssp_resp(&cli->pwd, cli->domain, - cli->user_name, cli->calling.name, + create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain, + cli->usr.user_name, cli->calling.name, cli->ntlmssp_cli_flgs, &auth_resp); prs_link(NULL, &auth_resp, NULL); @@ -3172,10 +3189,10 @@ BOOL cli_establish_connection(struct cli_state *cli, *p_oem++ = gssapi_len & 0xff; /* second session negotiation stage */ - if (!cli_session_setup_x(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->usr.user_name, pwd_buf, buf_len, NULL, 0, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3202,12 +3219,12 @@ BOOL cli_establish_connection(struct cli_state *cli, } } } - else if (cli->pwd.cleartext || cli->pwd.null_pwd) + else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd) { fstring passwd, ntpasswd; int pass_len = 0, ntpass_len = 0; - if (cli->pwd.null_pwd) + if (cli->usr.pwd.null_pwd) { /* attempt null session */ passwd[0] = ntpasswd[0] = 0; @@ -3216,15 +3233,15 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); + pwd_get_cleartext(&(cli->usr.pwd), passwd); pass_len = strlen(passwd); } /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, + if (!cli_session_setup(cli, cli->usr.user_name, passwd, pass_len, ntpasswd, ntpass_len, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3257,23 +3274,23 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->use_ntlmv2 != False) { DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, - cli->user_name, calling->name, cli->domain); + pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, + cli->usr.user_name, calling->name, cli->usr.domain); } else { DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); } - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd, + pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd, &nt_sess_pwd_len, cli->sess_key); /* attempt encrypted session */ - if (!cli_session_setup_x(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->usr.user_name, (char*)lm_sess_pwd, sizeof(lm_sess_pwd), (char*)nt_sess_pwd, nt_sess_pwd_len, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); @@ -3384,7 +3401,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) */ make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope); - pwd_set_nullpwd(&cli->pwd); + pwd_set_nullpwd(&cli->usr.pwd); if (!cli_establish_connection(cli, remote_machine, &dest_ip, &calling, &called, -- cgit From b9b04afc354edc56c9dad8a861b4e4c8854e3d8e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 27 Nov 1999 22:14:37 +0000 Subject: modified cli_connect_serverlist to take server list of format \\server_name \\other_server etc. (This used to be commit 4fd4aeb57455792bd8eaf81f8fa45bca6bd3e2e2) --- source3/libsmb/clientgen.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 94cd89e342..06fa97df0c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -3360,6 +3360,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) extern pstring global_myname; extern pstring scope; fstring remote_machine; + fstring desthost; struct in_addr dest_ip; struct nmb_name calling, called, stupid_smbserver_called; BOOL connected_ok = False; @@ -3382,7 +3383,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) standard_sub_basic(remote_machine); strupper(remote_machine); - if (!resolve_name( remote_machine, &dest_ip, 0x20)) + if (!resolve_srv_name( remote_machine, desthost, &dest_ip)) { DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); continue; @@ -3394,8 +3395,8 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) continue; } - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); + make_nmb_name(&calling, global_myname, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); /* stupid microsoft destruction of the ability of netbios * to provide multiple netbios servers on one host. */ @@ -3403,11 +3404,11 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) pwd_set_nullpwd(&cli->usr.pwd); - if (!cli_establish_connection(cli, remote_machine, &dest_ip, + if (!cli_establish_connection(cli, desthost, &dest_ip, &calling, &called, "IPC$", "IPC", False, True) && - !cli_establish_connection(cli, remote_machine, &dest_ip, + !cli_establish_connection(cli, desthost, &dest_ip, &calling, &stupid_smbserver_called, "IPC$", "IPC", False, True)) -- cgit From 6ddfc68e0496dc41f8c9a022a0b04a2066b43c9d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 02:15:14 +0000 Subject: sys_select added one more argument (read, write selectors). (This used to be commit e4d92ff9dfc51735e6932748f66a7c20b2c1cb6a) --- source3/libsmb/clientgen.c | 72 +++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 52 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 06fa97df0c..f3bd08895d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -918,9 +918,11 @@ BOOL cli_session_setup_x(struct cli_state *cli, } static BOOL cli_calc_session_pwds(struct cli_state *cli, + char *myhostname, char *pword, char *ntpword, char *pass, int *passlen, char *ntpass, int *ntpasslen, + char *sess_key, BOOL ntlmv2) { BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL; @@ -998,59 +1000,23 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, } else if (ntpasslen != NULL) { - /* passlen != 0, ntpasslen != 0 && server supports encryption */ - if (ntlmv2) + if (cli->use_ntlmv2 != False) { - /* plain-text password requesting to be encrypted */ - uchar *srv_key = (uchar *)cli->cryptkey; - uchar nt_owf[16]; - uchar kr[16]; - HMACMD5Context ctx; - - SMBgenclientchals(cli->lm_cli_chal, - cli->nt_cli_chal, - &cli->nt_cli_chal_len, - cli->calling.name, - cli->usr.domain); - - nt_owf_gen(pword, nt_owf); - ntv2_owf_gen(nt_owf, cli->usr.user_name, cli->usr.domain, kr); - - /* lm # */ - memcpy(pword, cli->lm_cli_chal, 8); - SMBOWFencrypt_ntv2(kr, - srv_key, 8, - cli->lm_cli_chal, 8, - &pword[8]); - *passlen = 24; - - /* nt # */ - memcpy(ntpword, cli->lm_cli_chal, cli->nt_cli_chal_len); - SMBOWFencrypt_ntv2(kr, - srv_key, 8, - cli->nt_cli_chal, cli->nt_cli_chal_len, - &ntpword[cli->nt_cli_chal_len]); - *ntpasslen = cli->nt_cli_chal_len + 16; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, - &ctx); - hmac_md5_final(cli->sess_key, &ctx); -#if DEBUG_PASSWORD - DEBUG(100,("session key:\n")); - dump_data(100, cli->sess_key, sizeof(cli->sess_key)); -#endif - + DEBUG(10,("cli_establish_connection: NTLMv2\n")); + pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, + cli->usr.user_name, myhostname, + cli->usr.domain); } else { - /* plain-text password requesting to be encrypted */ - uchar *key = (uchar *)cli->cryptkey; - SMBencrypt ((uchar *)pass , key,(uchar *)pword ); - SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); - *passlen = 24; - *ntpasslen = 24; + DEBUG(10,("cli_establish_connection: NTLMv1\n")); + pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); } + + pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass, + ntpasslen, sess_key); + + *passlen = 24; } return True; } @@ -1059,7 +1025,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, send a session setup ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, - char *user, + char *myhostname, char *user, char *pass, int passlen, char *ntpass, int ntpasslen, char *user_domain) @@ -1073,9 +1039,10 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(cli->usr.user_name, user); - return cli_calc_session_pwds(cli, pword, ntpword, + return cli_calc_session_pwds(cli, myhostname, pword, ntpword, pass, &passlen, - ntpass, &ntpasslen, cli->use_ntlmv2) && + ntpass, &ntpasslen, cli->sess_key, + cli->use_ntlmv2) && cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen, user_domain); } @@ -3238,7 +3205,8 @@ BOOL cli_establish_connection(struct cli_state *cli, } /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->usr.user_name, + if (!cli_session_setup(cli, calling->name, + cli->usr.user_name, passwd, pass_len, ntpasswd, ntpass_len, cli->usr.domain)) -- cgit From 106fe88be01f7ac7d1369e97a6468dcd80c0a813 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 16:39:51 +0000 Subject: 1) when no domain used in ntlogin test command, should use default one from previous lsaquery command. over-ridden from DOMAIN\username 2) initialisation of cli_state is a little more specific: sets use_ntlmv2 to Auto. this can always be over-ridden. 3) fixed reusage of ntlmssp_cli_flgs which was being a pain 4) added pwd_compare() function then fixed bug in cli_use where NULL domain name was making connections multiply unfruitfully 5) type-casting of mallocs and Reallocs that cause ansi-c compilers to bitch (This used to be commit 301a6efaf67ddc96e6dcfd21b45a82863ff8f39a) --- source3/libsmb/clientgen.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f3bd08895d..5a0363185f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2675,8 +2675,18 @@ initialise a client structure ****************************************************************************/ void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) { - copy_user_creds(&cli->usr, usr); - cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; + if (usr != NULL) + { + copy_user_creds(&cli->usr, usr); + cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; + } + else + { + cli->usr.domain[0] = 0; + cli->usr.user_name[0] = 0; + pwd_set_nullpwd(&cli->usr.pwd); + cli->ntlmssp_cli_flgs = 0; + } } /**************************************************************************** @@ -2715,7 +2725,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) } cli->initialised = 1; - cli->capabilities = CAP_DFS; + cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32; + cli->use_ntlmv2 = Auto; + + cli_init_creds(cli, NULL); return cli; } @@ -2984,6 +2997,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) { /* common to both session setups */ + uint32 ntlmssp_flgs; char pwd_buf[128]; int buf_len; char *p; @@ -3024,9 +3038,7 @@ BOOL cli_establish_connection(struct cli_state *cli, p = skip_string(p, 1); CVAL(p, 0) = 0x1; p += 4; - if (cli->ntlmssp_cli_flgs == 0) - { - cli->ntlmssp_cli_flgs = + ntlmssp_flgs = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_SIGN | @@ -3036,11 +3048,7 @@ BOOL cli_establish_connection(struct cli_state *cli, NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_00001000 | NTLMSSP_NEGOTIATE_00002000; -#if 0 - cli->ntlmssp_cli_flgs = 0x80008207; -#endif - } - SIVAL(p, 0, cli->ntlmssp_cli_flgs); + SIVAL(p, 0, ntlmssp_flgs); p += 4; p += 16; /* skip some NULL space */ CVAL(p, 0) = 0; p++; /* alignment */ @@ -3072,12 +3080,12 @@ BOOL cli_establish_connection(struct cli_state *cli, } p = smb_buf(cli->inbuf) + 0x2f; - cli->ntlmssp_cli_flgs = IVAL(p, 0); /* 0x80808a05; */ + ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */ p += 4; memcpy(cli->cryptkey, p, 8); #ifdef DEBUG_PASSWORD DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n", - cli->ntlmssp_cli_flgs)); + ntlmssp_flgs)); DEBUG(100,("cli_session_setup_x: crypt key\n")); dump_data(100, cli->cryptkey, 8); @@ -3098,7 +3106,7 @@ BOOL cli_establish_connection(struct cli_state *cli, create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain, cli->usr.user_name, cli->calling.name, - cli->ntlmssp_cli_flgs, + ntlmssp_flgs, &auth_resp); prs_link(NULL, &auth_resp, NULL); -- cgit From 5988d0cdae19d014a5a011de83c48326e82860b6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 18:49:28 +0000 Subject: added get_any_dc_name() function. (This used to be commit 455e17dbb7d451b462004f302f5c68770f17b65e) --- source3/libsmb/clientgen.c | 154 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 32 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5a0363185f..7124211286 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2935,7 +2935,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, + const char *dest_host, struct in_addr *dest_ip, struct nmb_name *calling, struct nmb_name *called, char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) @@ -3328,17 +3328,104 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } +BOOL cli_connect_auth(struct cli_state *cli, + const char* desthost, + struct in_addr *dest_ip, + const struct user_credentials *usr) +{ + extern pstring global_myname; + extern pstring scope; + struct nmb_name calling, called; + if (!cli_initialise(cli)) + { + DEBUG(0,("unable to initialise client connection.\n")); + return False; + } + + make_nmb_name(&calling, global_myname, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); + + cli_init_creds(cli, usr); + + if (!cli_establish_connection(cli, desthost, dest_ip, + &calling, &called, + "IPC$", "IPC", + False, True)) + { + cli_shutdown(cli); + return False; + } + + return True; +} + +/**************************************************************************** + connect to one of multiple servers: don't care which +****************************************************************************/ +BOOL cli_connect_servers_auth(struct cli_state *cli, + char *p, + const struct user_credentials *usr) +{ + fstring remote_host; + BOOL connected_ok = False; + + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) + { + fstring desthost; + struct in_addr dest_ip; + strupper(remote_host); + + if (!resolve_srv_name( remote_host, desthost, &dest_ip)) + { + DEBUG(1,("Can't resolve address for %s\n", remote_host)); + continue; + } + + if (!cli_connect_auth(cli, desthost, &dest_ip, usr) && + !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr)) + { + continue; + } + + if (cli->protocol < PROTOCOL_LANMAN2 || + !IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + DEBUG(1,("machine %s not in user level security mode\n", + remote_host)); + cli_shutdown(cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + + connected_ok = True; + break; + } + + if (!connected_ok) + { + DEBUG(0,("Domain password server not available.\n")); + cli_shutdown(cli); + } + + return connected_ok; +} + /**************************************************************************** connect to one of multiple servers: don't care which ****************************************************************************/ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) { - extern pstring global_myname; - extern pstring scope; - fstring remote_machine; + fstring remote_host; fstring desthost; struct in_addr dest_ip; - struct nmb_name calling, called, stupid_smbserver_called; BOOL connected_ok = False; /* @@ -3346,58 +3433,43 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) * PDC/BDC. Contact each in turn and try and authenticate. */ - while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) + while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) { ZERO_STRUCTP(cli); if (!cli_initialise(cli)) { - DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n")); return False; } - standard_sub_basic(remote_machine); - strupper(remote_machine); + standard_sub_basic(remote_host); + strupper(remote_host); - if (!resolve_srv_name( remote_machine, desthost, &dest_ip)) + if (!resolve_srv_name( remote_host, desthost, &dest_ip)) { - DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); + DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host)); continue; } if ((lp_security() != SEC_USER) && (ismyip(dest_ip))) { - DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); + DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host)); continue; } - make_nmb_name(&calling, global_myname, 0x0 , scope); - make_nmb_name(&called , desthost , 0x20, scope); - /* stupid microsoft destruction of the ability of netbios - * to provide multiple netbios servers on one host. - */ - make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope); - - pwd_set_nullpwd(&cli->usr.pwd); - - if (!cli_establish_connection(cli, desthost, &dest_ip, - &calling, &called, - "IPC$", "IPC", - False, True) && - !cli_establish_connection(cli, desthost, &dest_ip, - &calling, &stupid_smbserver_called, - "IPC$", "IPC", - False, True)) + if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) && + !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL)) { - cli_shutdown(cli); continue; - } + } + if (cli->protocol < PROTOCOL_LANMAN2 || !IS_BITS_SET_ALL(cli->sec_mode, 1)) { DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", - remote_machine)); + remote_host)); cli_shutdown(cli); continue; } @@ -3679,3 +3751,21 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } +BOOL get_any_dc_name(const char *domain, char *srv_name) +{ + struct cli_state cli; + + if (!cli_connect_servers_auth(&cli, + get_trusted_serverlist(domain), NULL)) + { + return False; + } + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, cli.desthost); + strupper(srv_name); + + cli_shutdown(&cli); + + return True; +} -- cgit From 848ed55e22d30bcc072b197574bf1e1cc6c05c84 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 20:16:34 +0000 Subject: new get_any_dc_name() function allows lookups of trusted domains from lp_trusted_domains() parameter, so trusted domain logins should work, right, if you put user = TRUSTED_DOMAIN\NTuser in "domain name map", right? right - as _long_ as you're not using NTLMv2, because the damn NT username gets mapped to the damn unix name too early, and NTLMv2 challenge-responses are based on the client's user name, client's domain name, client's host name etc damn etc. so it becomes necessary to stop using char* username because this allows for massive amounts of confusion as to which username is being referred to. the underlying unix username on the local unix system that is associated with the smbd process that represents the NT username? or the NT username itself? (This used to be commit dd3ccdd7d996c107766cdad3c403e8b8947b9e65) --- source3/libsmb/clientgen.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7124211286..5f898a8b0e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,8 +31,18 @@ extern int DEBUGLEVEL; * set the port that will be used for connections by the client */ -void copy_user_creds(struct user_credentials *to, const struct user_credentials *from) +void copy_user_creds(struct user_credentials *to, + const struct user_credentials *from) { + if (from == NULL) + { + to->domain[0] = 0; + to->user_name[0] = 0; + pwd_set_nullpwd(&to->pwd); + to->ntlmssp_flags = 0; + + return; + } safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1); safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); @@ -2675,18 +2685,7 @@ initialise a client structure ****************************************************************************/ void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) { - if (usr != NULL) - { - copy_user_creds(&cli->usr, usr); - cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; - } - else - { - cli->usr.domain[0] = 0; - cli->usr.user_name[0] = 0; - pwd_set_nullpwd(&cli->usr.pwd); - cli->ntlmssp_cli_flgs = 0; - } + copy_user_creds(&cli->usr, usr); } /**************************************************************************** @@ -3336,6 +3335,8 @@ BOOL cli_connect_auth(struct cli_state *cli, extern pstring global_myname; extern pstring scope; struct nmb_name calling, called; + + ZERO_STRUCTP(cli); if (!cli_initialise(cli)) { DEBUG(0,("unable to initialise client connection.\n")); @@ -3412,7 +3413,6 @@ BOOL cli_connect_servers_auth(struct cli_state *cli, if (!connected_ok) { DEBUG(0,("Domain password server not available.\n")); - cli_shutdown(cli); } return connected_ok; @@ -3485,7 +3485,6 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) if (!connected_ok) { DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); - cli_shutdown(cli); } return connected_ok; -- cgit From 7d01f964ff3c1a11bd72d987312f9826fee1c124 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 18:16:08 +0000 Subject: cool! a unix socket smb redirector. code based on smbfilter and ideas from ssh-agent. the intent is to be able to share smb sessions using cli_net_use_add() across multiple processes, where one process knows the target server name, user name and domain, but not the smb password. (This used to be commit 294b653f2e9cdc1864ec638ae8b4300df25723cf) --- source3/libsmb/clientgen.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5f898a8b0e..218ab67758 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2930,6 +2930,104 @@ BOOL cli_reestablish_connection(struct cli_state *cli) return False; } +static int cli_init_redirect(struct cli_state *cli, + const char* srv_name, struct in_addr *destip, + const struct user_credentials *usr) +{ + int sock; + struct sockaddr_un sa; + fstring ip_name; + struct cli_state cli_redir; + + pstring data; + uint32 len; + char *p; + char *in = cli->inbuf; + char *out = cli->outbuf; + + if (strequal(srv_name, "*SMBSERVER")) + { + fstrcpy(ip_name, "\\\\"); + inet_aton(&ip_name[2], destip); + srv_name = ip_name; + } + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + + if (sock < 0) + { + DEBUG(0, ("unix socket open failed\n")); + return sock; + } + + ZERO_STRUCT(sa); + sa.sun_family = AF_UNIX; + safe_strcpy(sa.sun_path, "/tmp/smb-agent/smb.sock", + sizeof(sa.sun_path)-1); + + DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); + + if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) + { + DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); + close(sock); + return False; + } + + DEBUG(10,("connect succeeded\n")); + + ZERO_STRUCT(data); + + p = &data[4]; + safe_strcpy(p, srv_name, 16); + p = skip_string(p, 1); + safe_strcpy(p, usr != NULL ? usr->user_name : "", 16); + p = skip_string(p, 1); + safe_strcpy(p, usr != NULL ? usr->domain : "", 16); + p = skip_string(p, 1); + + if (usr != NULL && !pwd_is_nullpwd(&usr->pwd)) + { + uchar lm16[16]; + uchar nt16[16]; + + pwd_get_lm_nt_16(&usr->pwd, lm16, nt16); + memcpy(p, lm16, 16); + p += 16; + memcpy(p, nt16, 16); + p += 16; + } + + len = PTR_DIFF(p, data); + SIVAL(data, 0, len); + + printf("data len: %d\n", len); + out_data(stdout, data, len, 80); + + if (write(sock, data, len) <= 0) + { + DEBUG(0,("write failed\n")); + close(sock); + return False; + } + + len = read(sock, &cli_redir, sizeof(cli_redir)); + + if (len != sizeof(cli_redir)) + { + DEBUG(0,("read failed\n")); + close(sock); + return False; + } + + memcpy(cli, &cli_redir, sizeof(cli_redir)); + cli->inbuf = in; + cli->outbuf = out; + cli->fd = sock; + + return sock; +} + /**************************************************************************** establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ @@ -2957,6 +3055,19 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + if (cli->fd == -1 && cli->redirect) + { + if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr)) + { + DEBUG(10,("cli_establish_connection: redirected OK\n")); + return True; + } + else + { + DEBUG(10,("redirect FAILED\n")); + return False; + } + } if (cli->fd == -1) { if (!cli_connect(cli, dest_host, dest_ip)) -- cgit From 6eebe18fa9682f570127b08fb116ab561223de22 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 19:55:34 +0000 Subject: smb-agent improvements. added -D (daemon) option. smb agent is restricted to connections from the current user (socket is created with current user uid). (This used to be commit 5af076e4b7ee13eebe0b89748e3f5a1ef21f8c73) --- source3/libsmb/clientgen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 218ab67758..176be9948b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2938,6 +2938,7 @@ static int cli_init_redirect(struct cli_state *cli, struct sockaddr_un sa; fstring ip_name; struct cli_state cli_redir; + fstring path; pstring data; uint32 len; @@ -2945,6 +2946,8 @@ static int cli_init_redirect(struct cli_state *cli, char *in = cli->inbuf; char *out = cli->outbuf; + slprintf(path, sizeof(path)-1, "/tmp/smb-agent/smb.%d", getuid()); + if (strequal(srv_name, "*SMBSERVER")) { fstrcpy(ip_name, "\\\\"); @@ -2962,8 +2965,7 @@ static int cli_init_redirect(struct cli_state *cli, ZERO_STRUCT(sa); sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, "/tmp/smb-agent/smb.sock", - sizeof(sa.sun_path)-1); + safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); -- cgit From c2a3b11b0738f57accafe19c84b682f761fa9631 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 22:02:03 +0000 Subject: starting "connection reuse" system in smb-agent. added version number which isn't actually used right now :-) (This used to be commit d54a64ae3ab7cdc1ac67fb49f7255e6a106d624e) --- source3/libsmb/clientgen.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 176be9948b..3695680301 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -40,6 +40,7 @@ void copy_user_creds(struct user_credentials *to, to->user_name[0] = 0; pwd_set_nullpwd(&to->pwd); to->ntlmssp_flags = 0; + to->reuse = False; return; } @@ -47,6 +48,7 @@ void copy_user_creds(struct user_credentials *to, safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); to->ntlmssp_flags = from->ntlmssp_flags; + to->reuse = from->reuse; }; int cli_set_port(struct cli_state *cli, int port) @@ -785,6 +787,12 @@ BOOL cli_session_setup_x(struct cli_state *cli, char *p; BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; + if (cli->usr.reuse) + { + DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n")); + return True; + } + DEBUG(100,("cli_session_setup. extended security: %s\n", BOOLSTR(esec))); @@ -1063,6 +1071,12 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { + if (cli->usr.reuse) + { + DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n")); + return True; + } + bzero(cli->outbuf,smb_size); set_message(cli->outbuf,2,0,True); CVAL(cli->outbuf,smb_com) = SMBulogoffX; @@ -2981,6 +2995,12 @@ static int cli_init_redirect(struct cli_state *cli, ZERO_STRUCT(data); p = &data[4]; + SSVAL(p, 0, 0); + p += 2; + + SSVAL(p, 0, usr->reuse ? AGENT_CMD_CON_REUSE : AGENT_CMD_CON); + p += 2; + safe_strcpy(p, srv_name, 16); p = skip_string(p, 1); safe_strcpy(p, usr != NULL ? usr->user_name : "", 16); -- cgit From 0ca1f87930a57dfd2510b98443423d8a67cfa70b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 23:36:53 +0000 Subject: argh! smb-agent redirection client reusage is a nightmare! moved smb-agent over to a single-process model instead of fork() in order to reuse client connections. except, of course, you can't do a select() on the same socket connections! argh! (This used to be commit e9e5a34de8e8f9a69e817aceb8c16284334d4642) --- source3/libsmb/clientgen.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3695680301..985d1c496d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2960,7 +2960,7 @@ static int cli_init_redirect(struct cli_state *cli, char *in = cli->inbuf; char *out = cli->outbuf; - slprintf(path, sizeof(path)-1, "/tmp/smb-agent/smb.%d", getuid()); + slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid()); if (strequal(srv_name, "*SMBSERVER")) { @@ -3023,8 +3023,10 @@ static int cli_init_redirect(struct cli_state *cli, len = PTR_DIFF(p, data); SIVAL(data, 0, len); - printf("data len: %d\n", len); - out_data(stdout, data, len, 80); +#ifdef DEBUG_PASSWORD + DEBUG(100,("data len: %d\n", len)); + dump_data(100, data, len); +#endif if (write(sock, data, len) <= 0) { @@ -3046,6 +3048,7 @@ static int cli_init_redirect(struct cli_state *cli, cli->inbuf = in; cli->outbuf = out; cli->fd = sock; + cli->usr.reuse = False; return sock; } -- cgit From 8a8a7da5186596ee86b0b188156bca7d5e664784 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 00:49:13 +0000 Subject: argh! you wouldn't believe what i had to do: use the mid (multiplex id) to redirect multiple socket-based connnections onto a single client state. argh! (This used to be commit 06390e792cd8aa57a91c3a3d1d267fd1bcdc17a1) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 985d1c496d..fea105887f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1597,7 +1597,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int total = -1; int issued=0; int received=0; - int mpx = MAX(cli->max_mux-1, 1); + int mpx = MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT); int block = (cli->max_xmit - (smb_size+32)) & ~1023; int mid; int blocks = (size + (block-1)) / block; -- cgit From f521205cb3d188fdcadcbd205dcfda4a7dcb89a0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 19:14:37 +0000 Subject: jeremy is going to hate me for this. created an "nmb-agent" utility that, yes: it connects to the 137 socket and accepts unix socket connections which it redirects onto port 137. it uses the name_trn_id field to filter requests to the correct location. name_query() and name_status() are the first victims to use this feature (by specifying a file descriptor of -1). (This used to be commit d923bc8da2cf996408194d98381409191dd81a16) --- source3/libsmb/clientgen.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fea105887f..86edfa8bec 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2949,7 +2949,6 @@ static int cli_init_redirect(struct cli_state *cli, const struct user_credentials *usr) { int sock; - struct sockaddr_un sa; fstring ip_name; struct cli_state cli_redir; fstring path; @@ -2969,29 +2968,13 @@ static int cli_init_redirect(struct cli_state *cli, srv_name = ip_name; } - sock = socket(AF_UNIX, SOCK_STREAM, 0); + sock = open_pipe_sock(path); if (sock < 0) { - DEBUG(0, ("unix socket open failed\n")); return sock; } - ZERO_STRUCT(sa); - sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); - - DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); - - if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) - { - DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); - close(sock); - return False; - } - - DEBUG(10,("connect succeeded\n")); - ZERO_STRUCT(data); p = &data[4]; -- 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/libsmb/clientgen.c | 76 ++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 56 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 86edfa8bec..49772cd37a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,26 +31,6 @@ extern int DEBUGLEVEL; * set the port that will be used for connections by the client */ -void copy_user_creds(struct user_credentials *to, - const struct user_credentials *from) -{ - if (from == NULL) - { - to->domain[0] = 0; - to->user_name[0] = 0; - pwd_set_nullpwd(&to->pwd); - to->ntlmssp_flags = 0; - to->reuse = False; - - return; - } - safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1); - safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); - memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); - to->ntlmssp_flags = from->ntlmssp_flags; - to->reuse = from->reuse; -}; - int cli_set_port(struct cli_state *cli, int port) { @@ -787,7 +767,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, char *p; BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; - if (cli->usr.reuse) + if (cli->reuse) { DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n")); return True; @@ -1071,7 +1051,7 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { - if (cli->usr.reuse) + if (cli->reuse) { DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n")); return True; @@ -2697,9 +2677,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) /**************************************************************************** initialise a client structure ****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) +void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { - copy_user_creds(&cli->usr, usr); + copy_nt_creds(&cli->usr, usr); } /**************************************************************************** @@ -2946,18 +2926,19 @@ BOOL cli_reestablish_connection(struct cli_state *cli) static int cli_init_redirect(struct cli_state *cli, const char* srv_name, struct in_addr *destip, - const struct user_credentials *usr) + const struct ntuser_creds *usr) { int sock; fstring ip_name; struct cli_state cli_redir; fstring path; - pstring data; uint32 len; - char *p; + char *data; char *in = cli->inbuf; char *out = cli->outbuf; + prs_struct ps; + uint16 command; slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid()); @@ -2975,42 +2956,25 @@ static int cli_init_redirect(struct cli_state *cli, return sock; } - ZERO_STRUCT(data); - - p = &data[4]; - SSVAL(p, 0, 0); - p += 2; - - SSVAL(p, 0, usr->reuse ? AGENT_CMD_CON_REUSE : AGENT_CMD_CON); - p += 2; - - safe_strcpy(p, srv_name, 16); - p = skip_string(p, 1); - safe_strcpy(p, usr != NULL ? usr->user_name : "", 16); - p = skip_string(p, 1); - safe_strcpy(p, usr != NULL ? usr->domain : "", 16); - p = skip_string(p, 1); + command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON; - if (usr != NULL && !pwd_is_nullpwd(&usr->pwd)) + if (!create_ntuser_creds(&ps, srv_name, 0x0, command, usr, cli->reuse)) { - uchar lm16[16]; - uchar nt16[16]; - - pwd_get_lm_nt_16(&usr->pwd, lm16, nt16); - memcpy(p, lm16, 16); - p += 16; - memcpy(p, nt16, 16); - p += 16; + DEBUG(0,("could not parse credentials\n")); + close(sock); + return False; } - len = PTR_DIFF(p, data); - SIVAL(data, 0, len); + len = ps.offset; + data = mem_data(&ps.data, 0); #ifdef DEBUG_PASSWORD DEBUG(100,("data len: %d\n", len)); dump_data(100, data, len); #endif + SIVAL(data, 0, len); + if (write(sock, data, len) <= 0) { DEBUG(0,("write failed\n")); @@ -3031,7 +2995,7 @@ static int cli_init_redirect(struct cli_state *cli, cli->inbuf = in; cli->outbuf = out; cli->fd = sock; - cli->usr.reuse = False; + cli->reuse = False; return sock; } @@ -3449,7 +3413,7 @@ BOOL cli_establish_connection(struct cli_state *cli, BOOL cli_connect_auth(struct cli_state *cli, const char* desthost, struct in_addr *dest_ip, - const struct user_credentials *usr) + const struct ntuser_creds *usr) { extern pstring global_myname; extern pstring scope; @@ -3484,7 +3448,7 @@ BOOL cli_connect_auth(struct cli_state *cli, ****************************************************************************/ BOOL cli_connect_servers_auth(struct cli_state *cli, char *p, - const struct user_credentials *usr) + const struct ntuser_creds *usr) { fstring remote_host; BOOL connected_ok = False; -- cgit From 12ca139d5cb79f7e61a84d7dfe8a4c64ed56d82b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 9 Dec 1999 07:06:12 +0000 Subject: OK. This code works on a RedHat 6.0 system. However smbpasswd time out of sending the session setup on Solaris 2.6. No idea. I'll work on it some tomorrow. This is to fix the "Unable to setup password vectors" thingy. Also changed an inet_aton() to inet_addr() as the former is not very portable :-) Luke, I set the redir flag to false because the connection to the smb-agent was failing and smbpasswd bombed. Double check me on this one. -jc (This used to be commit e1d2b174caf5f0c48a8fac25778f72a868ec6eb7) --- source3/libsmb/clientgen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 49772cd37a..50bf54d02c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1337,7 +1337,9 @@ int cli_nt_create(struct cli_state *cli, const char *fname) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli, True); + if (!cli_send_smb(cli, True)) { + return -1; + } if (!cli_receive_smb(cli)) { return -1; } @@ -2945,7 +2947,7 @@ static int cli_init_redirect(struct cli_state *cli, if (strequal(srv_name, "*SMBSERVER")) { fstrcpy(ip_name, "\\\\"); - inet_aton(&ip_name[2], destip); + destip->s_addr = inet_addr(&ip_name[2]); srv_name = ip_name; } -- 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/libsmb/clientgen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 50bf54d02c..27efc132c0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2926,7 +2926,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) return False; } -static int cli_init_redirect(struct cli_state *cli, +static BOOL cli_init_redirect(struct cli_state *cli, const char* srv_name, struct in_addr *destip, const struct ntuser_creds *usr) { @@ -2955,7 +2955,7 @@ static int cli_init_redirect(struct cli_state *cli, if (sock < 0) { - return sock; + return False; } command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON; @@ -3038,8 +3038,7 @@ BOOL cli_establish_connection(struct cli_state *cli, } else { - DEBUG(10,("redirect FAILED\n")); - return False; + DEBUG(10,("redirect FAILED, make direct connection\n")); } } if (cli->fd == -1) -- 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/libsmb/clientgen.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 27efc132c0..62c7429b59 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1337,9 +1337,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname) pstrcpy(p,fname); p = skip_string(p,1); - if (!cli_send_smb(cli, True)) { - return -1; - } + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -2947,7 +2945,7 @@ static BOOL cli_init_redirect(struct cli_state *cli, if (strequal(srv_name, "*SMBSERVER")) { fstrcpy(ip_name, "\\\\"); - destip->s_addr = inet_addr(&ip_name[2]); + inet_aton(&ip_name[2], destip); srv_name = ip_name; } -- 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/libsmb/clientgen.c | 1916 +++++++++++++++----------------------------- 1 file changed, 663 insertions(+), 1253 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 62c7429b59..4f620bc5f4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,8 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client generic functions - Copyright (C) Andrew Tridgell 1994-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + Copyright (C) Andrew Tridgell 1994-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 @@ -25,84 +24,52 @@ #include "includes.h" #include "trans2.h" + extern int DEBUGLEVEL; +extern pstring user_socket_options; +extern pstring scope; -/* - * set the port that will be used for connections by the client - */ +static void cli_process_oplock(struct cli_state *cli); +/* + * Change the port number used to call on + */ int cli_set_port(struct cli_state *cli, int port) { - - if (port != 0) + if (port > 0) cli->port = port; - return cli->port; /* return it incase caller wants it */ - + return cli->port; } /**************************************************************************** -copy a string (unicode or otherwise) into an SMB buffer. skips a string -plus points to next +recv an smb ****************************************************************************/ -static char *cli_put_string(struct cli_state *cli, char *p, const char *str, - BOOL skip_end) +static BOOL cli_receive_smb(struct cli_state *cli) { - uint16 flgs2 = SVAL(cli->outbuf, smb_flg2); - if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) - { - p = align2(p, cli->outbuf); - p = ascii_to_unibuf(p, str, 1024); - if (skip_end) - { - CVAL(p, 0) = 0; p++; - CVAL(p, 0) = 0; p++; - } - return p; - } - else - { - pstrcpy(p, str); - p = skip_string(p, 1); - if (skip_end) - { - CVAL(p, 0) = 0; p++; + BOOL ret; + again: + ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + + if (ret) { + /* it might be an oplock break request */ + if (CVAL(cli->inbuf,smb_com) == SMBlockingX && + SVAL(cli->inbuf,smb_vwv6) == 0 && + SVAL(cli->inbuf,smb_vwv7) == 0) { + if (cli->use_oplocks) cli_process_oplock(cli); + /* try to prevent loops */ + CVAL(cli->inbuf,smb_com) = 0xFF; + goto again; } - return p; - } -} - -/**************************************************************************** -copy a string (unicode or otherwise) into an SMB buffer. skips a string -plus points to next -****************************************************************************/ -static const char *cli_get_string(struct cli_state *cli, char *p, - char *str, size_t str_len) -{ - uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); - if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) - { - return unibuf_to_ascii(str, p, str_len); } - else - { - safe_strcpy(str, p, str_len-1); - return skip_string(p, 1); - } -} -/**************************************************************************** -recv an smb -****************************************************************************/ -static BOOL cli_receive_smb(struct cli_state *cli) -{ - return client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + return ret; } /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli, BOOL show) +static BOOL cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; @@ -111,26 +78,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) len = smb_len(cli->outbuf) + 4; - if (show) - { - uint8 msg_type = CVAL(cli->outbuf, 0); - if (msg_type == 0) - { - show_msg(cli->outbuf); - } - else - { - dump_data(10, cli->outbuf, len); - } - } - while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) - { - DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n", - strerror(errno))); - + if (ret <= 0 && errno == EPIPE && !reestablished) { if (cli_reestablish_connection(cli)) { reestablished = True; nwritten=0; @@ -139,8 +89,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) } if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", - len,ret)); - return False; + (int)len,(int)ret)); + close_sockets(); + exit(1); } nwritten += ret; } @@ -148,26 +99,62 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) return True; } -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) -{ - static fstring error_message; - cli_safe_errstr(cli, error_message, sizeof(error_message)); - return error_message; +/**************************************************************************** +setup basics in a outgoing packet +****************************************************************************/ +static void cli_setup_packet(struct cli_state *cli) +{ + cli->rap_error = 0; + cli->nt_error = 0; + SSVAL(cli->outbuf,smb_pid,cli->pid); + SSVAL(cli->outbuf,smb_uid,cli->vuid); + SSVAL(cli->outbuf,smb_mid,cli->mid); + if (cli->protocol > PROTOCOL_CORE) { + SCVAL(cli->outbuf,smb_flg,0x8); + SSVAL(cli->outbuf,smb_flg2,0x1); + } } + + /**************************************************************************** - return a description of an SMB error +process an oplock break request from the server ****************************************************************************/ -void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len) +static void cli_process_oplock(struct cli_state *cli) { - smb_safe_errstr(cli->inbuf, msg, len); + char *oldbuf = cli->outbuf; + pstring buf; + int fnum; + + fnum = SVAL(cli->inbuf,smb_vwv2); + + /* damn, we really need to keep a record of open files so we + can detect a oplock break and a close crossing on the + wire. for now this swallows the errors */ + if (fnum == 0) return; + + cli->outbuf = buf; + + memset(buf,'\0',smb_size); + set_message(buf,8,0,True); + + CVAL(buf,smb_com) = SMBlockingX; + SSVAL(buf,smb_tid, cli->cnum); + cli_setup_packet(cli); + SSVAL(buf,smb_vwv0,0xFF); + SSVAL(buf,smb_vwv1,0); + SSVAL(buf,smb_vwv2,fnum); + SSVAL(buf,smb_vwv3,2); /* oplock break ack */ + SIVAL(buf,smb_vwv4,0); /* timoeut */ + SSVAL(buf,smb_vwv6,0); /* unlockcount */ + SSVAL(buf,smb_vwv7,0); /* lockcount */ + + cli_send_smb(cli); + + cli->outbuf = oldbuf; } + /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -186,36 +173,36 @@ struct {2244, "This password cannot be used now (password history conflict)." }, {2245, "The password is shorter than required." }, {2246, "The password of this user is too recent to change."}, + + /* these really shouldn't be here ... */ + {0x80, "Not listening on called name"}, + {0x81, "Not listening for calling name"}, + {0x82, "Called name not present"}, + {0x83, "Called name present, but insufficient resources"}, + {0, NULL} }; /**************************************************************************** - return a description of a RAP error + return a description of an SMB error ****************************************************************************/ -BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen) +static char *cli_smb_errstr(struct cli_state *cli) { - int i; - - slprintf(err_msg, msglen - 1, "RAP code %d", rap_error); - - for (i = 0; rap_errmap[i].message != NULL; i++) - { - if (rap_errmap[i].err == rap_error) - { - safe_strcpy( err_msg, rap_errmap[i].message, msglen); - return True; - } - } - return False; + return smb_errstr(cli->inbuf); } -/**************************************************************************** - return a description of an SMB error -****************************************************************************/ -void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen) +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) { + static fstring error_message; uint8 errclass; uint32 errnum; + uint32 nt_rpc_error; + int i; /* * Errors are of three kinds - smb errors, @@ -224,54 +211,50 @@ void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen) * errors, whose error code is in cli.rap_error. */ - cli_error(cli, &errclass, &errnum); + cli_error(cli, &errclass, &errnum, &nt_rpc_error); if (errclass != 0) { - cli_safe_smb_errstr(cli, err_msg, msglen); + return cli_smb_errstr(cli); } - else if (cli->nt_error) - { - /* - * Was it an NT error ? - */ - (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen); - } - else + /* + * Was it an NT error ? + */ + + if (nt_rpc_error) { - /* - * Must have been a rap error. - */ - (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen); + char *nt_msg = get_nt_error_msg(nt_rpc_error); + + if (nt_msg == NULL) + { + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); + } + else + { + fstrcpy(error_message, nt_msg); + } + + return error_message; } -} -/**************************************************************************** -setup basics in a outgoing packet -****************************************************************************/ -static void cli_setup_packet(struct cli_state *cli) -{ - uint16 flgs2 = 0; - flgs2 |= FLAGS2_LONG_PATH_COMPONENTS; - flgs2 |= FLAGS2_32_BIT_ERROR_CODES; - flgs2 |= FLAGS2_EXT_SEC; -#if 0 - flgs2 |= FLAGS2_UNICODE_STRINGS; -#endif - cli->rap_error = 0; - cli->nt_error = 0; - SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->vuid); - SSVAL(cli->outbuf,smb_mid,cli->mid); + /* + * Must have been a rap error. + */ - if (cli->protocol > PROTOCOL_CORE) + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) { - SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,flgs2); - } -} + if (rap_errmap[i].err == cli->rap_error) + { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + return error_message; +} /***************************************************************************** Convert a character pointer in a cli_call_api() response to a form we can use. @@ -299,7 +282,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter, /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -BOOL cli_send_trans(struct cli_state *cli, int trans, +static BOOL cli_send_trans(struct cli_state *cli, int trans, char *name, int pipe_name_len, int fid, int flags, uint16 *setup, int lsetup, int msetup, @@ -315,7 +298,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,14+lsetup,0,True); CVAL(cli->outbuf,smb_com) = trans; SSVAL(cli->outbuf,smb_tid, cli->cnum); @@ -353,7 +336,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - cli_send_smb(cli, True); + show_msg(cli->outbuf); + cli_send_smb(cli); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -387,13 +371,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, if (trans==SMBtrans2) SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ if (this_lparam) /* param[] */ - memcpy(outparam,param,this_lparam); + memcpy(outparam,param+tot_param,this_lparam); if (this_ldata) /* data[] */ - memcpy(outdata,data,this_ldata); + memcpy(outdata,data+tot_data,this_ldata); set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - cli_send_smb(cli, True); + show_msg(cli->outbuf); + cli_send_smb(cli); tot_data += this_ldata; tot_param += this_lparam; @@ -414,12 +399,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; - + uint8 eclass; + uint32 ecode; + *data_len = *param_len = 0; if (!cli_receive_smb(cli)) return False; + show_msg(cli->inbuf); + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -428,9 +417,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, return(False); } - if (cli_error(cli, NULL, NULL)) + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + + if (cli_error(cli, &eclass, &ecode, NULL)) { - return(False); + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); } /* parse out the lengths */ @@ -472,6 +468,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; + show_msg(cli->inbuf); + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -479,10 +477,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - - if (cli_error(cli, NULL, NULL)) + if (cli_error(cli, &eclass, &ecode, NULL)) { - return(False); + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); } } @@ -642,6 +640,8 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c int type = SVAL(p,14); int comment_offset = IVAL(p,16) & 0xFFFF; char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + dos_to_unix(sname,True); + dos_to_unix(cmnt,True); fn(sname, type, cmnt); } } else { @@ -719,6 +719,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + dos_to_unix(sname, True); + dos_to_unix(cmnt, True); fn(sname, stype, cmnt); } } @@ -754,41 +756,76 @@ prots[] = /**************************************************************************** -send a session setup + Send a session setup. The username is in UNIX character format and must be + converted to DOS codepage format before sending. If the password is in + plaintext, the same should be done. ****************************************************************************/ -BOOL cli_session_setup_x(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *user_domain) + +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup) { - uint8 eclass; - uint32 ecode; char *p; - BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; + fstring pword, ntpword; - if (cli->reuse) - { - DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n")); + if (cli->protocol < PROTOCOL_LANMAN1) return True; - } - DEBUG(100,("cli_session_setup. extended security: %s\n", - BOOLSTR(esec))); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli_session_setup. pass, ntpass\n")); - dump_data(100, pass, passlen); - dump_data(100, ntpass, ntpasslen); -#endif + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + return False; + } - if (cli->protocol < PROTOCOL_LANMAN1) - { - return True; + if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + /* Null session connect. */ + pword[0] = '\0'; + ntpword[0] = '\0'; + } else { + if ((cli->sec_mode & 2) && passlen != 24) { + /* + * Encrypted mode needed, and non encrypted password supplied. + */ + passlen = 24; + ntpasslen = 24; + fstrcpy(pword, pass); + unix_to_dos(pword,True); + fstrcpy(ntpword, ntpass);; + unix_to_dos(ntpword,True); + SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); + SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); + } else if ((cli->sec_mode & 2) && passlen == 24) { + /* + * Encrypted mode needed, and encrypted password supplied. + */ + memcpy(pword, pass, passlen); + if(ntpasslen == 24) { + memcpy(ntpword, ntpass, ntpasslen); + } else { + fstrcpy(ntpword, ""); + ntpasslen = 0; + } + } else { + /* + * Plaintext mode needed, assume plaintext supplied. + */ + fstrcpy(pword, pass); + unix_to_dos(pword,True); + fstrcpy(ntpword, ""); + ntpasslen = 0; + } } + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) { + fstrcpy(pword, ""); + passlen=1; + fstrcpy(ntpword, ""); + ntpasslen=1; + } + /* send a session setup command */ - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); if (cli->protocol < PROTOCOL_NT1) { @@ -803,36 +840,13 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); p = smb_buf(cli->outbuf); - memcpy(p,pass,passlen); + memcpy(p,pword,passlen); p += passlen; pstrcpy(p,user); + unix_to_dos(p,True); strupper(p); } - else if (esec) - { - set_message(cli->outbuf,12,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE); - p = smb_buf(cli->outbuf); - memcpy(p,pass,passlen); - p += passlen; - - p = cli_put_string(cli, p, "Unix", False); - p = cli_put_string(cli, p, "Samba", False); - p = cli_put_string(cli, p, "", False); - p++; - - set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - } - else + else { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; @@ -845,228 +859,76 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SIVAL(cli->outbuf,smb_vwv11, 0); + SSVAL(cli->outbuf,smb_vwv11,0); p = smb_buf(cli->outbuf); - memcpy(p,pass,passlen); + memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpass,ntpasslen); + memcpy(p,ntpword,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - strupper(user); - p = cli_put_string(cli, p, user, False); - strupper(user_domain); - p = cli_put_string(cli, p, user_domain, False); - p = cli_put_string(cli, p, "Unix", True); - p = cli_put_string(cli, p, "Samba", False); - + pstrcpy(p,user); + unix_to_dos(p,True); + strupper(p); + p = skip_string(p,1); + pstrcpy(p,workgroup); + strupper(p); + p = skip_string(p,1); + pstrcpy(p,"Unix");p = skip_string(p,1); + pstrcpy(p,"Samba");p = skip_string(p,1); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli, True); - if (!cli_receive_smb(cli)) - { - DEBUG(10,("cli_session_setup_x: receive smb failed\n")); + cli_send_smb(cli); + if (!cli_receive_smb(cli)) return False; - } - - if (cli_error(cli, &eclass, &ecode)) - { - uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); - if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES)) - { - if (ecode != ERRmoredata || !esec) - { - return False; - } - } - else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */ - { - return False; - } - } - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) - { - if (esec) - { - } - else - { - /* - * Save off some of the connected server - * info. - */ - char *server_domain; - char *server_os; - char *server_type; + show_msg(cli->inbuf); - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } - fstrcpy(cli->server_os, server_os); - fstrcpy(cli->server_type, server_type); - fstrcpy(cli->server_domain, server_domain); - } + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); + + if (cli->protocol >= PROTOCOL_NT1) { + /* + * Save off some of the connected server + * info. + */ + char *server_domain,*server_os,*server_type; + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + fstrcpy(cli->server_os, server_os); + dos_to_unix(cli->server_os, True); + fstrcpy(cli->server_type, server_type); + dos_to_unix(cli->server_type, True); + fstrcpy(cli->server_domain, server_domain); + dos_to_unix(cli->server_domain, True); } + fstrcpy(cli->user_name, user); + dos_to_unix(cli->user_name, True); + return True; } -static BOOL cli_calc_session_pwds(struct cli_state *cli, - char *myhostname, - char *pword, char *ntpword, - char *pass, int *passlen, - char *ntpass, int *ntpasslen, - char *sess_key, - BOOL ntlmv2) +/**************************************************************************** + Send a uloggoff. +*****************************************************************************/ + +BOOL cli_ulogoff(struct cli_state *cli) { - BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL; + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,2,0,True); + CVAL(cli->outbuf,smb_com) = SMBulogoffX; + cli_setup_packet(cli); + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - if (pass == NULL || passlen == NULL) - { - DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n")); - return False; - } - if ((ntpass != NULL || ntpasslen != NULL) && - (ntpass == NULL || ntpasslen == NULL)) - { - DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n")); - return False; - } - -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n")); - dump_data(100, pass, *passlen); - if (ntpass_ok) - { - dump_data(100, ntpass, *ntpasslen); - } -#endif - if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - /* if in share level security then don't send a password now */ - pword[0] = '\0'; - *passlen=1; - if (ntpass_ok) - { - ntpword[0] = '\0'; - *ntpasslen=1; - } - return True; - } - else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0')) - { - /* Null session connect. */ - pword [0] = '\0'; - if (ntpass_ok) - { - ntpword[0] = '\0'; - *ntpasslen=0; - } - - return True; - } - - if (!ntpass_ok) - { - return False; - } - - if (*passlen == 24 && *ntpasslen >= 24) - { - if (IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* encrypted password, implicit from 24-byte lengths */ - memcpy(pword , pass , *passlen); - memcpy(ntpword, ntpass, *ntpasslen); - } - else - { - DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n")); - return False; - } - } - else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* plain-text password: server doesn't support encrypted. */ - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - *ntpasslen = 0; - } - else if (ntpasslen != NULL) - { - if (cli->use_ntlmv2 != False) - { - DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, - cli->usr.user_name, myhostname, - cli->usr.domain); - } - else - { - DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); - } - - pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass, - ntpasslen, sess_key); - - *passlen = 24; - } - return True; -} - -/**************************************************************************** -send a session setup -****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - char *myhostname, char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *user_domain) -{ - fstring pword, ntpword; - - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) - { - return False; - } - - fstrcpy(cli->usr.user_name, user); - - return cli_calc_session_pwds(cli, myhostname, pword, ntpword, - pass, &passlen, - ntpass, &ntpasslen, cli->sess_key, - cli->use_ntlmv2) && - cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen, - user_domain); -} - -/**************************************************************************** - Send a uloggoff. -*****************************************************************************/ - -BOOL cli_ulogoff(struct cli_state *cli) -{ - if (cli->reuse) - { - DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n")); - return True; - } - - bzero(cli->outbuf,smb_size); - set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBulogoffX; - cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - - cli_send_smb(cli, True); - if (!cli_receive_smb(cli)) - return False; + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; return CVAL(cli->inbuf,smb_rcls) == 0; } @@ -1077,10 +939,10 @@ send a tconX BOOL cli_send_tconX(struct cli_state *cli, char *share, char *dev, char *pass, int passlen) { - fstring fullshare, pword; + fstring fullshare, pword, dos_pword; char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); fstrcpy(cli->share, share); @@ -1091,17 +953,32 @@ BOOL cli_send_tconX(struct cli_state *cli, } if ((cli->sec_mode & 2) && *pass && passlen != 24) { + /* + * Non-encrypted passwords - convert to DOS codepage before encryption. + */ passlen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + fstrcpy(dos_pword,pass); + unix_to_dos(dos_pword,True); + SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); } else { - memcpy(pword, pass, passlen); + if(!(cli->sec_mode & 2)) { + /* + * Non-encrypted passwords - convert to DOS codepage before using. + */ + fstrcpy(pword,pass); + unix_to_dos(pword,True); + } else { + memcpy(pword, pass, passlen); + } } slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); + unix_to_dos(fullshare, True); strupper(fullshare); - set_message(cli->outbuf,4, 0, True); + set_message(cli->outbuf,4, + 2 + strlen(fullshare) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -1111,15 +988,14 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p = cli_put_string(cli, p, fullshare, False); - fstrcpy(p, dev); - p = skip_string(p, 1); - - set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False); + fstrcpy(p,fullshare); + p = skip_string(p,1); + pstrcpy(p,dev); + unix_to_dos(p,True); SCVAL(cli->inbuf,smb_rcls, 1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; @@ -1129,10 +1005,8 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); - if (cli->protocol >= PROTOCOL_NT1) - { - cli_get_string(cli, smb_buf(cli->inbuf), - cli->dev, sizeof(cli->dev)); + if (cli->protocol >= PROTOCOL_NT1) { + fstrcpy(cli->dev, smb_buf(cli->inbuf)); } if (strcasecmp(share,"IPC$")==0) { @@ -1140,8 +1014,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) - { + if (cli->protocol >= PROTOCOL_NT1 && + smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ cli->win95 = True; } @@ -1156,13 +1030,13 @@ send a tree disconnect ****************************************************************************/ BOOL cli_tdis(struct cli_state *cli) { - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBtdis; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; @@ -1176,8 +1050,8 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); @@ -1190,11 +1064,13 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,fname_src); + unix_to_dos(p,True); p = skip_string(p,1); *p++ = 4; pstrcpy(p,fname_dst); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1213,8 +1089,8 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,1, 2 + strlen(fname),True); @@ -1227,8 +1103,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,fname); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1247,8 +1124,8 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0, 2 + strlen(dname),True); @@ -1259,8 +1136,9 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,dname); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1279,8 +1157,8 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0, 2 + strlen(dname),True); @@ -1291,8 +1169,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,dname); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1309,12 +1188,12 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) /**************************************************************************** open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, const char *fname) +int cli_nt_create(struct cli_state *cli, char *fname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,24,1 + strlen(fname),True); @@ -1335,9 +1214,10 @@ int cli_nt_create(struct cli_state *cli, const char *fname) p = smb_buf(cli->outbuf); pstrcpy(p,fname); + unix_to_dos(p,True); p = skip_string(p,1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return -1; } @@ -1353,8 +1233,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname) /**************************************************************************** open a file ****************************************************************************/ -int cli_open(struct cli_state *cli, const char *fname, - int flags, int share_mode) +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) { char *p; unsigned openfn=0; @@ -1389,8 +1268,8 @@ int cli_open(struct cli_state *cli, const char *fname, } #endif /* O_SYNC */ - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,15,1 + strlen(fname),True); @@ -1404,13 +1283,21 @@ int cli_open(struct cli_state *cli, const char *fname, SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); SSVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv8,openfn); + + if (cli->use_oplocks) { + /* if using oplocks then ask for a batch oplock via + core and extended methods */ + CVAL(cli->outbuf,smb_flg) |= + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; + SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); + } p = smb_buf(cli->outbuf); - p = cli_put_string(cli, p, fname, False); - - set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False); + pstrcpy(p,fname); + unix_to_dos(p,True); + p = skip_string(p,1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return -1; } @@ -1430,8 +1317,8 @@ int cli_open(struct cli_state *cli, const char *fname, ****************************************************************************/ BOOL cli_close(struct cli_state *cli, int fnum) { - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,3,0,True); @@ -1442,7 +1329,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1463,8 +1350,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti char *p; int saved_timeout = cli->timeout; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0', smb_size); set_message(cli->outbuf,8,10,True); @@ -1483,7 +1370,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli, True); + cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1508,8 +1395,8 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,8,10,True); @@ -1529,7 +1416,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1549,8 +1436,8 @@ issue a single SMBread and don't wait for a reply static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,10,0,True); @@ -1565,7 +1452,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli, True); + cli_send_smb(cli); } /**************************************************************************** @@ -1577,15 +1464,24 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int total = -1; int issued=0; int received=0; - int mpx = MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT); +/* + * There is a problem in this code when mpx is more than one. + * for some reason files can get corrupted when being read. + * Until we understand this fully I am serializing reads (one + * read/one reply) for now. JRA. + */ +#if 0 + int mpx = MAX(cli->max_mux-1, 1); +#else + int mpx = 1; +#endif int block = (cli->max_xmit - (smb_size+32)) & ~1023; int mid; int blocks = (size + (block-1)) / block; if (size == 0) return 0; - while (received < blocks) - { + while (received < blocks) { int size2; while (issued - received < mpx && issued < blocks) { @@ -1602,8 +1498,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t mid = SVAL(cli->inbuf, smb_mid) - cli->mid; size2 = SVAL(cli->inbuf, smb_vwv5); - if (cli_error(cli, NULL, NULL)) - { + if (CVAL(cli->inbuf,smb_rcls) != 0) { blocks = MIN(blocks, mid-1); continue; } @@ -1647,8 +1542,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,12,size,True); @@ -1673,7 +1568,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli, True); + show_msg(cli->outbuf); + cli_send_smb(cli); } /**************************************************************************** @@ -1687,58 +1583,98 @@ ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size) { - int total = -1; - int issued=0; - int received=0; + int bwritten = 0; + int issued = 0; + int received = 0; int mpx = MAX(cli->max_mux-1, 1); int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int mid; int blocks = (size + (block-1)) / block; - if (size == 0) return 0; - while (received < blocks) { - int size2; - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, size-issued*block); - cli_issue_write(cli, fnum, offset+issued*block, + while ((issued - received < mpx) && (issued < blocks)) + { + int bsent = issued * block; + int size1 = MIN(block, size - bsent); + + cli_issue_write(cli, fnum, offset + bsent, write_mode, - buf + issued*block, + buf + bsent, size1, issued); issued++; } - if (!cli_receive_smb(cli)) { - return total; + if (!cli_receive_smb(cli)) + { + return bwritten; } received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; - size2 = SVAL(cli->inbuf, smb_vwv2); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; + if (CVAL(cli->inbuf,smb_rcls) != 0) + { + break; } - total += size2; - - total = MAX(total, mid*block + size2); + bwritten += SVAL(cli->inbuf, smb_vwv2); } - while (received < issued) { - cli_receive_smb(cli); + while (received < issued && cli_receive_smb(cli)) + { received++; } + return bwritten; +} + + +/**************************************************************************** + write to a file using a SMBwrite and not bypassing 0 byte writes +****************************************************************************/ +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1) +{ + char *p; + ssize_t total = 0; + + do { + size_t size = MIN(size1, cli->max_xmit - 48); + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,5, 3 + size,True); + + CVAL(cli->outbuf,smb_com) = SMBwrite; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SSVAL(cli->outbuf,smb_vwv1,size); + SIVAL(cli->outbuf,smb_vwv2,offset); + SSVAL(cli->outbuf,smb_vwv4,0); + + p = smb_buf(cli->outbuf); + *p++ = 1; + SSVAL(p, 0, size); + memcpy(p+2, buf, size); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size = SVAL(cli->inbuf,smb_vwv0); + if (size == 0) break; + + size1 -= size; + total += size; + } while (size1); + return total; } @@ -1750,10 +1686,10 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBgetattrE; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1761,7 +1697,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1802,8 +1738,8 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0,strlen(fname)+2,True); @@ -1814,8 +1750,9 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); + unix_to_dos(p+1,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1848,8 +1785,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,8,strlen(fname)+4,True); @@ -1863,10 +1800,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); + unix_to_dos(p+1,True); p = skip_string(p,1); *p = 4; - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1899,6 +1837,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, memset(param, 0, param_len); SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); + unix_to_dos(¶m[6],True); do { ret = (cli_send_trans(cli, SMBtrans2, @@ -1916,7 +1855,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode); + cli_error(cli, &eclass, &ecode, NULL); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); } @@ -1972,6 +1911,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, memset(param, 0, param_len); SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); pstrcpy(¶m[6], fname); + unix_to_dos(¶m[6],True); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, /* name, length */ @@ -2009,7 +1949,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 40); + *size = IVAL(rdata, 48); } if (ino) { *ino = IVAL(rdata, 64); @@ -2081,7 +2021,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 40); + *size = IVAL(rdata, 48); } if (ino) { *ino = IVAL(rdata, 64); @@ -2117,6 +2057,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); pstrcpy(finfo->name,p+27); + dos_to_unix(finfo->name,True); } return(28 + CVAL(p,26)); @@ -2129,6 +2070,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); pstrcpy(finfo->name,p+31); + dos_to_unix(finfo->name,True); } return(32 + CVAL(p,30)); @@ -2142,6 +2084,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); pstrcpy(finfo->name,p+33); + dos_to_unix(finfo->name,True); } return(SVAL(p,4)+4); @@ -2154,6 +2097,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); pstrcpy(finfo->name,p+37); + dos_to_unix(finfo->name,True); } return(SVAL(p,4)+4); @@ -2189,7 +2133,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 4; /* EA size */ p += 2; /* short name len? */ p += 24; /* short name? */ - StrnCpy(finfo->name,p,namelen); + StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); + dos_to_unix(finfo->name,True); return(ret); } return(SVAL(p,0)); @@ -2217,7 +2162,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int dirlist_len = 0; int total_received = -1; BOOL First = True; - int ff_resume_key = 0; int ff_searchcount=0; int ff_eos=0; int ff_lastname=0; @@ -2230,6 +2174,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, pstring param; pstrcpy(mask,Mask); + unix_to_dos(mask,True); while (ff_eos == 0) { loop_count++; @@ -2253,12 +2198,12 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); - SIVAL(param,6,ff_resume_key); /* ff_resume_key */ + SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ pstrcpy(param+12,mask); - DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_resume_key,ff_lastname,mask)); + DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_lastname,mask)); } if (!cli_send_trans(cli, SMBtrans2, @@ -2279,7 +2224,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode); + cli_error(cli, &eclass, &ecode, NULL); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); continue; @@ -2311,19 +2256,19 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, switch(info_level) { case 260: - ff_resume_key =0; StrnCpy(mask,p+ff_lastname, - data_len-ff_lastname); + MIN(sizeof(mask)-1,data_len-ff_lastname)); break; case 1: pstrcpy(mask,p + ff_lastname + 1); - ff_resume_key = 0; break; } } else { pstrcpy(mask,""); } - + + dos_to_unix(mask, True); + /* and add them to the dirlist pool */ dirlist = Realloc(dirlist,dirlist_len + data_len); @@ -2347,8 +2292,10 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, if (rdata) free(rdata); rdata = NULL; if (rparam) free(rparam); rparam = NULL; - DEBUG(3,("received %d entries (eos=%d resume=%d)\n", - ff_searchcount,ff_eos,ff_resume_key)); + DEBUG(3,("received %d entries (eos=%d)\n", + ff_searchcount,ff_eos)); + + if (ff_searchcount > 0) loop_count = 0; First = False; } @@ -2383,6 +2330,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; + pstring dos_new_password; if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); @@ -2408,19 +2356,22 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); fstrcpy(upper_case_old_pw, old_password); + unix_to_dos(upper_case_old_pw,True); strupper(upper_case_old_pw); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - if (!make_oem_passwd_hash( data, new_password, old_pw_hash, False)) - { - return False; - } + pstrcpy(dos_new_password, new_password); + unix_to_dos(dos_new_password, True); + + if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) + return False; /* * Now place the old password hash in the data. */ memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); fstrcpy(upper_case_new_pw, new_password); + unix_to_dos(upper_case_new_pw,True); strupper(upper_case_new_pw); E_P16((uchar *)upper_case_new_pw, new_pw_hash); @@ -2429,14 +2380,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; - if (!cli_send_trans(cli,SMBtrans, + if (cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ data,data_len,0 /* data, length, max */ - )) - { + ) == False) { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; @@ -2466,7 +2416,7 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ for (plength=0,numprots=0; @@ -2482,6 +2432,7 @@ BOOL cli_negprot(struct cli_state *cli) numprots++) { *p++ = 2; pstrcpy(p,prots[numprots].name); + unix_to_dos(p,True); p += strlen(p) + 1; } @@ -2490,11 +2441,11 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) - { return False; - } + + show_msg(cli->inbuf); if (CVAL(cli->inbuf,smb_rcls) != 0 || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { @@ -2504,56 +2455,28 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol >= PROTOCOL_NT1) - { - char *buf = smb_buf(cli->inbuf); - int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct))); + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); - cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; + cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); + cli->serverzone *= 60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE)) - { + if (cli->capabilities & 1) { cli->readbraw_supported = True; cli->writebraw_supported = True; } - - if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) - { - /* oops, some kerberos-related nonsense. */ - /* expect to have to use NTLMSSP-over-SMB */ - DEBUG(10,("unknown kerberos-related (?) blob\n")); - memset(cli->cryptkey, 0, 8); - cli->server_domain[0] = 0; - } - else - { - memcpy(cli->cryptkey, buf,8); - if (bcc > 8) - { - unibuf_to_ascii(cli->server_domain, buf+8, - sizeof(cli->server_domain)); - } - else - { - cli->server_domain[0] = 0; - } - DEBUG(5,("server's domain: %s bcc: %d\n", - cli->server_domain, bcc)); - } - } - else if (cli->protocol >= PROTOCOL_LANMAN1) - { + } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + cli->serverzone = SVALS(cli->inbuf,smb_vwv10); + cli->serverzone *= 60; /* this time is converted to GMT by make_unix_date */ cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); @@ -2584,11 +2507,6 @@ BOOL cli_session_request(struct cli_state *cli, memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); - if (cli->port == 445) - { - return True; - } - /* put in the destination name */ p = cli->outbuf+len; name_mangle(cli->called .name, p, cli->called .name_type); @@ -2607,12 +2525,41 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli, True); + cli_send_smb(cli); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) return False; + if (CVAL(cli->inbuf,0) == 0x84) { + /* C. Hoch 9/14/95 Start */ + /* For information, here is the response structure. + * We do the byte-twiddling to for portability. + struct RetargetResponse{ + unsigned char type; + unsigned char flags; + int16 length; + int32 ip_addr; + int16 port; + }; + */ + int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); + /* SESSION RETARGET */ + putip((char *)&cli->dest_ip,cli->inbuf+4); + + close_sockets(); + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); + if (cli->fd == -1) + return False; + + DEBUG(3,("Retargeted\n")); + + set_socket_options(cli->fd,user_socket_options); + + /* Try again */ + return cli_session_request(cli, calling, called); + } /* C. Hoch 9/14/95 End */ + #ifdef WITH_SSL if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ if (!sslutil_fd_is_ssl(cli->fd)){ @@ -2624,7 +2571,7 @@ retry: if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ - cli->rap_error = CVAL(cli->inbuf,0); + cli->rap_error = CVAL(cli->inbuf,4); return False; } return(True); @@ -2637,7 +2584,6 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern struct in_addr ipzero; - int port = cli->port; fstrcpy(cli->desthost, host); @@ -2650,38 +2596,19 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) cli->dest_ip = *ip; } - - if (port == 0) port = SMB_PORT2; + if (cli->port == 0) cli->port = 139; /* Set to default */ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - port, cli->timeout); + cli->port, cli->timeout); if (cli->fd == -1) - { - if (cli->port != 0) - { - return False; - } - port = SMB_PORT; - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - port, cli->timeout); - if (cli->fd == -1) return False; - } + return False; - cli->port = port; + set_socket_options(cli->fd,user_socket_options); return True; } -/**************************************************************************** -initialise a client structure -****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) -{ - copy_nt_creds(&cli->usr, usr); -} - /**************************************************************************** initialise a client structure ****************************************************************************/ @@ -2707,7 +2634,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->mid = 1; cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; - cli->timeout = 20000; + cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); @@ -2717,39 +2644,19 @@ struct cli_state *cli_initialise(struct cli_state *cli) return False; } - cli->initialised = 1; - cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32; - cli->use_ntlmv2 = Auto; + memset(cli->outbuf, '\0', cli->bufsize); + memset(cli->inbuf, '\0', cli->bufsize); - cli_init_creds(cli, NULL); + cli->initialised = 1; return cli; } -/**************************************************************************** -close the socket descriptor -****************************************************************************/ -void cli_close_socket(struct cli_state *cli) -{ -#ifdef WITH_SSL - if (cli->fd != -1) - { - sslutil_disconnect(cli->fd); - } -#endif /* WITH_SSL */ - if (cli->fd != -1) - { - close(cli->fd); - } - cli->fd = -1; -} - /**************************************************************************** shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - DEBUG(10,("cli_shutdown\n")); if (cli->outbuf) { free(cli->outbuf); @@ -2758,7 +2665,12 @@ void cli_shutdown(struct cli_state *cli) { free(cli->inbuf); } - cli_close_socket(cli); +#ifdef WITH_SSL + if (cli->fd != -1) + sslutil_disconnect(cli->fd); +#endif /* WITH_SSL */ + if (cli->fd != -1) + close(cli->fd); memset(cli, 0, sizeof(*cli)); } @@ -2771,43 +2683,34 @@ void cli_shutdown(struct cli_state *cli) for 32 bit "warnings", a return code of 0 is expected. ****************************************************************************/ -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) { - int flgs2; + int flgs2 = SVAL(cli->inbuf,smb_flg2); char rcls; int code; - if (!cli->initialised) - { - DEBUG(0,("cli_error: client state uninitialised!\n")); - return EINVAL; - } - - flgs2 = SVAL(cli->inbuf,smb_flg2); - if (eclass) *eclass = 0; if (num ) *num = 0; + if (nt_rpc_error) *nt_rpc_error = cli->nt_error; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) - { + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* 32 bit error codes detected */ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - switch (nt_err & 0xFFFFFF) - { - case NT_STATUS_ACCESS_VIOLATION : return EACCES; - case NT_STATUS_NO_SUCH_FILE : return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE : return ENODEV; - case NT_STATUS_INVALID_HANDLE : return EBADF; - case NT_STATUS_NO_MEMORY : return ENOMEM; - case NT_STATUS_ACCESS_DENIED : return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION : return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID : return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + switch (nt_err & 0xFFFFFF) { + case NT_STATUS_ACCESS_VIOLATION: return EACCES; + case NT_STATUS_NO_SUCH_FILE: return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; + case NT_STATUS_INVALID_HANDLE: return EBADF; + case NT_STATUS_NO_MEMORY: return ENOMEM; + case NT_STATUS_ACCESS_DENIED: return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION: return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; } /* for all other cases - a default code */ @@ -2830,7 +2733,6 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRrename: return EEXIST; case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; - case ERRmoredata: return 0; /* Informational only */ } } if (rcls == ERRSRV) { @@ -2886,37 +2788,30 @@ BOOL cli_reestablish_connection(struct cli_state *cli) /* copy the parameters necessary to re-establish the connection */ if (cli->cnum != 0) - { - do_tcon = True; - } - - if (do_tcon) { fstrcpy(share, cli->share); fstrcpy(dev , cli->dev); + do_tcon = True; } memcpy(&called , &(cli->called ), sizeof(called )); memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->desthost); + fstrcpy(dest_host, cli->full_dest_host_name); DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", nmb_namestr(&calling), nmb_namestr(&called), inet_ntoa(cli->dest_ip), - cli->usr.user_name, cli->usr.domain)); + cli->user_name, cli->domain)); cli->fd = -1; if (cli_establish_connection(cli, dest_host, &cli->dest_ip, &calling, &called, - share, dev, False, do_tcon)) - { - if (cli->fd != oldfd) - { - if (dup2(cli->fd, oldfd) == oldfd) - { - cli_close_socket(cli); + share, dev, False, do_tcon)) { + if (cli->fd != oldfd) { + if (dup2(cli->fd, oldfd) == oldfd) { + close(cli->fd); } } return True; @@ -2924,101 +2819,18 @@ BOOL cli_reestablish_connection(struct cli_state *cli) return False; } -static BOOL cli_init_redirect(struct cli_state *cli, - const char* srv_name, struct in_addr *destip, - const struct ntuser_creds *usr) -{ - int sock; - fstring ip_name; - struct cli_state cli_redir; - fstring path; - - uint32 len; - char *data; - char *in = cli->inbuf; - char *out = cli->outbuf; - prs_struct ps; - uint16 command; - - slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid()); - - if (strequal(srv_name, "*SMBSERVER")) - { - fstrcpy(ip_name, "\\\\"); - inet_aton(&ip_name[2], destip); - srv_name = ip_name; - } - - sock = open_pipe_sock(path); - - if (sock < 0) - { - return False; - } - - command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON; - - if (!create_ntuser_creds(&ps, srv_name, 0x0, command, usr, cli->reuse)) - { - DEBUG(0,("could not parse credentials\n")); - close(sock); - return False; - } - - len = ps.offset; - data = mem_data(&ps.data, 0); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("data len: %d\n", len)); - dump_data(100, data, len); -#endif - - SIVAL(data, 0, len); - - if (write(sock, data, len) <= 0) - { - DEBUG(0,("write failed\n")); - close(sock); - return False; - } - - len = read(sock, &cli_redir, sizeof(cli_redir)); - - if (len != sizeof(cli_redir)) - { - DEBUG(0,("read failed\n")); - close(sock); - return False; - } - - memcpy(cli, &cli_redir, sizeof(cli_redir)); - cli->inbuf = in; - cli->outbuf = out; - cli->fd = sock; - cli->reuse = False; - - return sock; -} - /**************************************************************************** establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ BOOL cli_establish_connection(struct cli_state *cli, - const char *dest_host, struct in_addr *dest_ip, + char *dest_host, struct in_addr *dest_ip, struct nmb_name *calling, struct nmb_name *called, char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) { - fstring callingstr; - fstring calledstr; - - nmb_safe_namestr(calling, callingstr, sizeof(callingstr)); - nmb_safe_namestr(called , calledstr , sizeof(calledstr )); - - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n", - callingstr, calledstr, inet_ntoa(*dest_ip), - cli->usr.user_name, cli->usr.domain, - cli->use_ntlmv2 ? "v2" : "v1")); + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); /* establish connection */ @@ -3027,24 +2839,12 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } - if (cli->fd == -1 && cli->redirect) - { - if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr)) - { - DEBUG(10,("cli_establish_connection: redirected OK\n")); - return True; - } - else - { - DEBUG(10,("redirect FAILED, make direct connection\n")); - } - } if (cli->fd == -1) { if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - callingstr, inet_ntoa(*dest_ip))); + nmb_namestr(calling), inet_ntoa(*dest_ip))); return False; } } @@ -3053,9 +2853,7 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session request\n")); if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } @@ -3063,242 +2861,33 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed negprot\n")); if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } - if (cli->usr.domain[0] == 0) + if (cli->pwd.cleartext || cli->pwd.null_pwd) { - safe_strcpy(cli->usr.domain, cli->server_domain, - sizeof(cli->usr.domain)); - } + fstring passwd; + int pass_len; - if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) - { - /* common to both session setups */ - uint32 ntlmssp_flgs; - char pwd_buf[128]; - int buf_len; - char *p; - char *e = pwd_buf + sizeof(pwd_buf); - - /* 1st session setup */ - char pwd_data[34] = - { - 0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e, - 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, - 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22, - 0x04, 0x20 - }; - /* 2nd session setup */ -#if 0 - char pwd_data_2[8] = - { - 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b - }; -#endif - char pwd_data_2[8] = - { - 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b - }; - prs_struct auth_resp; - int resp_len; - char *p_gssapi; - char *p_oem; - char *p_gssapi_end; - uint16 gssapi_len; - - memset(pwd_buf, 0, sizeof(pwd_buf)); - memcpy(pwd_buf, pwd_data, sizeof(pwd_data)); - p = pwd_buf + sizeof(pwd_data); - - safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); - p = skip_string(p, 1); - CVAL(p, 0) = 0x1; - p += 4; - ntlmssp_flgs = - NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_OEM | - NTLMSSP_NEGOTIATE_SIGN | - NTLMSSP_NEGOTIATE_SEAL | - NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | - NTLMSSP_NEGOTIATE_00001000 | - NTLMSSP_NEGOTIATE_00002000; - SIVAL(p, 0, ntlmssp_flgs); - p += 4; - p += 16; /* skip some NULL space */ - CVAL(p, 0) = 0; p++; /* alignment */ - - buf_len = PTR_DIFF(p, pwd_buf); - - /* first session negotiation stage */ - if (!cli_session_setup_x(cli, cli->usr.user_name, - pwd_buf, buf_len, - NULL, 0, - cli->usr.domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - - DEBUG(1,("1st session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - - p = smb_buf(cli->inbuf) + 0x2f; - ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */ - p += 4; - memcpy(cli->cryptkey, p, 8); -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n", - ntlmssp_flgs)); - - DEBUG(100,("cli_session_setup_x: crypt key\n")); - dump_data(100, cli->cryptkey, 8); -#endif - prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); - - if (cli->use_ntlmv2 != False) - { - DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, - cli->usr.user_name, calling->name, cli->usr.domain); - } - else - { - DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); - } - - create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain, - cli->usr.user_name, cli->calling.name, - ntlmssp_flgs, - &auth_resp); - prs_link(NULL, &auth_resp, NULL); - - memset(pwd_buf, 0, sizeof(pwd_buf)); - p = pwd_buf; - - CVAL(p, 0) = 0xa1; p++; - CVAL(p, 0) = 0x82; p++; - p_gssapi = p; p+= 2; - CVAL(p, 0) = 0x30; p++; - CVAL(p, 0) = 0x82; p++; - p += 2; - - CVAL(p, 0) = 0xa2; p++; - CVAL(p, 0) = 0x82; p++; - p_oem = p; p+= 2; - CVAL(p, 0) = 0x04; p++; - CVAL(p, 0) = 0x82; p++; - p += 2; - - p_gssapi_end = p; - - safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); - p = skip_string(p, 1); - CVAL(p, 0) = 0x3; - p += 4; - - resp_len = mem_buf_len(auth_resp.data); - mem_buf_copy(p, auth_resp.data, 0, resp_len); - prs_mem_free(&auth_resp); - - p += resp_len; - - buf_len = PTR_DIFF(p, pwd_buf); - gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12; - - *p_gssapi++ = (gssapi_len >> 8) & 0xff; - *p_gssapi++ = gssapi_len & 0xff; - - p_gssapi += 2; - gssapi_len -= 4; - - *p_gssapi++ = (gssapi_len >> 8) & 0xff; - *p_gssapi++ = gssapi_len & 0xff; - - gssapi_len -= 4; - - *p_oem++ = (gssapi_len >> 8) & 0xff; - *p_oem++ = gssapi_len & 0xff; - - p_oem += 2; - gssapi_len -= 4; - - *p_oem++ = (gssapi_len >> 8) & 0xff; - *p_oem++ = gssapi_len & 0xff; - - /* second session negotiation stage */ - if (!cli_session_setup_x(cli, cli->usr.user_name, - pwd_buf, buf_len, - NULL, 0, - cli->usr.domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - - DEBUG(1,("2nd session setup ok\n")); - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - NULL, 0)) - - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd) - { - fstring passwd, ntpasswd; - int pass_len = 0, ntpass_len = 0; - - if (cli->usr.pwd.null_pwd) + if (cli->pwd.null_pwd) { /* attempt null session */ - passwd[0] = ntpasswd[0] = 0; - pass_len = ntpass_len = 1; + passwd[0] = 0; + pass_len = 1; } else { /* attempt clear-text session */ - pwd_get_cleartext(&(cli->usr.pwd), passwd); + pwd_get_cleartext(&(cli->pwd), passwd); pass_len = strlen(passwd); } /* attempt clear-text session */ - if (!cli_session_setup(cli, calling->name, - cli->usr.user_name, + if (!cli_session_setup(cli, cli->user_name, passwd, pass_len, - ntpasswd, ntpass_len, - cli->usr.domain)) + NULL, 0, + cli->domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3324,68 +2913,25 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ + unsigned char nt_sess_pwd[24]; unsigned char lm_sess_pwd[24]; - unsigned char nt_sess_pwd[128]; - size_t nt_sess_pwd_len; - - if (cli->use_ntlmv2 != False) - { - DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, - cli->usr.user_name, calling->name, cli->usr.domain); - } - else - { - DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); - } - pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd, - &nt_sess_pwd_len, cli->sess_key); + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); /* attempt encrypted session */ - if (!cli_session_setup_x(cli, cli->usr.user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, nt_sess_pwd_len, - cli->usr.domain)) + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + (char*)nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) { DEBUG(1,("failed session setup\n")); - - if (cli->use_ntlmv2 == Auto) - { - DEBUG(10,("NTLMv2 failed. Using NTLMv1\n")); - cli->use_ntlmv2 = False; - if (do_tcon) - { - fstrcpy(cli->share, service); - fstrcpy(cli->dev, service_type); - } - fstrcpy(cli->desthost, dest_host); - cli_close_socket(cli); - return cli_establish_connection(cli, - dest_host, dest_ip, - calling, called, - service, service_type, - do_shutdown, do_tcon); - } - if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } - DEBUG(1,("session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - if (do_tcon) { if (!cli_send_tconX(cli, service, service_type, @@ -3393,184 +2939,18 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } } } if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return True; } -BOOL cli_connect_auth(struct cli_state *cli, - const char* desthost, - struct in_addr *dest_ip, - const struct ntuser_creds *usr) -{ - extern pstring global_myname; - extern pstring scope; - struct nmb_name calling, called; - - ZERO_STRUCTP(cli); - if (!cli_initialise(cli)) - { - DEBUG(0,("unable to initialise client connection.\n")); - return False; - } - - make_nmb_name(&calling, global_myname, 0x0 , scope); - make_nmb_name(&called , desthost , 0x20, scope); - - cli_init_creds(cli, usr); - - if (!cli_establish_connection(cli, desthost, dest_ip, - &calling, &called, - "IPC$", "IPC", - False, True)) - { - cli_shutdown(cli); - return False; - } - - return True; -} - -/**************************************************************************** - connect to one of multiple servers: don't care which -****************************************************************************/ -BOOL cli_connect_servers_auth(struct cli_state *cli, - char *p, - const struct ntuser_creds *usr) -{ - fstring remote_host; - BOOL connected_ok = False; - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) - { - fstring desthost; - struct in_addr dest_ip; - strupper(remote_host); - - if (!resolve_srv_name( remote_host, desthost, &dest_ip)) - { - DEBUG(1,("Can't resolve address for %s\n", remote_host)); - continue; - } - - if (!cli_connect_auth(cli, desthost, &dest_ip, usr) && - !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr)) - { - continue; - } - - if (cli->protocol < PROTOCOL_LANMAN2 || - !IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - DEBUG(1,("machine %s not in user level security mode\n", - remote_host)); - cli_shutdown(cli); - continue; - } - - /* - * We have an anonymous connection to IPC$. - */ - - connected_ok = True; - break; - } - - if (!connected_ok) - { - DEBUG(0,("Domain password server not available.\n")); - } - - return connected_ok; -} - -/**************************************************************************** - connect to one of multiple servers: don't care which -****************************************************************************/ -BOOL cli_connect_serverlist(struct cli_state *cli, char *p) -{ - fstring remote_host; - fstring desthost; - struct in_addr dest_ip; - BOOL connected_ok = False; - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) - { - ZERO_STRUCTP(cli); - - if (!cli_initialise(cli)) - { - DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n")); - return False; - } - - standard_sub_basic(remote_host); - strupper(remote_host); - - if (!resolve_srv_name( remote_host, desthost, &dest_ip)) - { - DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host)); - continue; - } - - if ((lp_security() != SEC_USER) && (ismyip(dest_ip))) - { - DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host)); - continue; - } - - if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) && - !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL)) - { - continue; - } - - - if (cli->protocol < PROTOCOL_LANMAN2 || - !IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", - remote_host)); - cli_shutdown(cli); - continue; - } - - /* - * We have an anonymous connection to IPC$. - */ - - connected_ok = True; - break; - } - - if (!connected_ok) - { - DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); - } - - return connected_ok; -} /**************************************************************************** cancel a print job @@ -3583,7 +2963,7 @@ int cli_printjob_del(struct cli_state *cli, int job) int rdrcnt,rprcnt, ret = -1; pstring param; - bzero(param,sizeof(param)); + memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ @@ -3624,7 +3004,7 @@ int cli_print_queue(struct cli_state *cli, int result_code=0; int i = -1; - bzero(param,sizeof(param)); + memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ @@ -3686,29 +3066,29 @@ check for existance of a dir ****************************************************************************/ BOOL cli_chkpath(struct cli_state *cli, char *path) { - fstring path2; + pstring path2; char *p; - fstrcpy(path2,path); + safe_strcpy(path2,path,sizeof(pstring)); trim_string(path2,NULL,"\\"); if (!*path2) *path2 = '\\'; - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,4 + strlen(path2),True); SCVAL(cli->outbuf,smb_com,SMBchkpth); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - p = smb_buf(cli->outbuf); *p++ = 4; - fstrcpy(p,path2); + safe_strcpy(p,path2,strlen(path2)); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; return True; } @@ -3723,7 +3103,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, char *p; /* send a SMBsendstrt command */ - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBsendstrt; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -3732,20 +3112,22 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,username); + unix_to_dos(p,True); p = skip_string(p,1); *p++ = 4; pstrcpy(p,host); + unix_to_dos(p,True); p = skip_string(p,1); set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; *grp = SVAL(cli->inbuf,smb_vwv0); @@ -3760,7 +3142,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) { char *p; - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,len+3,True); CVAL(cli->outbuf,smb_com) = SMBsendtxt; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -3772,13 +3154,13 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) *p = 1; SSVAL(p,1,len); memcpy(p+3,msg,len); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; return True; } @@ -3788,7 +3170,7 @@ end a message ****************************************************************************/ BOOL cli_message_end(struct cli_state *cli, int grp) { - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBsendend; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -3797,13 +3179,13 @@ BOOL cli_message_end(struct cli_state *cli, int grp) cli_setup_packet(cli); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; return True; } @@ -3814,13 +3196,13 @@ query disk space ****************************************************************************/ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBdskattr; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -3832,21 +3214,49 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } -BOOL get_any_dc_name(const char *domain, char *srv_name) +/**************************************************************************** + Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. +****************************************************************************/ + +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip) { - struct cli_state cli; + struct nmb_name calling, called; - if (!cli_connect_servers_auth(&cli, - get_trusted_serverlist(domain), NULL)) - { - return False; - } + make_nmb_name(&calling, srchost, 0x0, scope); - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, cli.desthost); - strupper(srv_name); + /* + * If the called name is an IP address + * then use *SMBSERVER immediately. + */ - cli_shutdown(&cli); + if(is_ipaddress(desthost)) + make_nmb_name(&called, "*SMBSERVER", 0x20, scope); + else + make_nmb_name(&called, desthost, 0x20, scope); - return True; + if (!cli_session_request(cli, &calling, &called)) { + struct nmb_name smbservername; + + /* + * If the name wasn't *SMBSERVER then + * try with *SMBSERVER if the first name fails. + */ + + cli_shutdown(cli); + + make_nmb_name(&smbservername , "*SMBSERVER", 0x20, scope); + + if (!nmb_name_equal(&called, &smbservername) || + !cli_initialise(cli) || + !cli_connect(cli, desthost, pdest_ip) || + !cli_session_request(cli, &calling, &smbservername)) { + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n", + desthost)); + cli_shutdown(cli); + return False; + } + } + + return True; } -- cgit From eb87c3fbdc83839ff7a0e4d3911d46b1d994d545 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Jan 2000 00:06:46 +0000 Subject: Fix for renaming directories on OS/2 server. Fix from John Janosik . Jeremy. (This used to be commit b3c0dd72339b2004684b1650c8f7832577bc44b0) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4f620bc5f4..1e230e2ff5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1059,7 +1059,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); p = smb_buf(cli->outbuf); *p++ = 4; -- cgit From 171da4d78736730557a94b44af9f2d62081b80ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2000 06:55:36 +0000 Subject: this looks like a big commit, but it isn't really :) This fixes our netbios scope handling. We now have a 'netbios scope' option in smb.conf and the scope option is removed from make_nmb_name() this was prompted by a bug in our PDC finding code where it didn't append the scope to the query of the '*' name. (This used to be commit b563be824b8c3141c49558eced7829b48d4ab26f) --- source3/libsmb/clientgen.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1e230e2ff5..0436fb9df5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -27,7 +27,6 @@ extern int DEBUGLEVEL; extern pstring user_socket_options; -extern pstring scope; static void cli_process_oplock(struct cli_state *cli); @@ -3223,7 +3222,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char { struct nmb_name calling, called; - make_nmb_name(&calling, srchost, 0x0, scope); + make_nmb_name(&calling, srchost, 0x0); /* * If the called name is an IP address @@ -3231,9 +3230,9 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char */ if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20, scope); + make_nmb_name(&called, "*SMBSERVER", 0x20); else - make_nmb_name(&called, desthost, 0x20, scope); + make_nmb_name(&called, desthost, 0x20); if (!cli_session_request(cli, &calling, &called)) { struct nmb_name smbservername; @@ -3245,7 +3244,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char cli_shutdown(cli); - make_nmb_name(&smbservername , "*SMBSERVER", 0x20, scope); + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); if (!nmb_name_equal(&called, &smbservername) || !cli_initialise(cli) || -- cgit From e8b5cb45155536107a71e1106ad4a624eb559496 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Jan 2000 10:15:53 +0000 Subject: cli_open() wasn't handling DENY_FCB or O_WRONLY correctly. After fixing that I needed to use O_RDWR instead of O_WRONLY in several places to avoid the silly bug in MS servers that doesn't allow getattrE on a file opened with O_WRONLY (This used to be commit e21aa4cb088f348139309d29c85c48c8b777cff5) --- source3/libsmb/clientgen.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0436fb9df5..e37974b570 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1231,6 +1231,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) /**************************************************************************** open a file +WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) { @@ -1238,12 +1239,6 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) unsigned openfn=0; unsigned accessmode=0; - /* you must open for RW not just write - otherwise getattrE doesn't - work! */ - if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) { - flags = (flags & ~O_ACCMODE) | O_RDWR; - } - if (flags & O_CREAT) openfn |= (1<<4); if (!(flags & O_EXCL)) { @@ -1267,6 +1262,10 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) } #endif /* O_SYNC */ + if (share_mode == DENY_FCB) { + accessmode = 0xFF; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); -- cgit From 735ee07018f4514771d26e01b41b0f02295b8b48 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jan 2000 13:40:27 +0000 Subject: don't treat a packet as a oplock break unless it is a request, not a reply! (This used to be commit 45b8f1c92cf7ecae35240e72741e5ac952587c58) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e37974b570..3b6403fe73 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -52,7 +52,8 @@ static BOOL cli_receive_smb(struct cli_state *cli) if (ret) { /* it might be an oplock break request */ - if (CVAL(cli->inbuf,smb_com) == SMBlockingX && + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && + CVAL(cli->inbuf,smb_com) == SMBlockingX && SVAL(cli->inbuf,smb_vwv6) == 0 && SVAL(cli->inbuf,smb_vwv7) == 0) { if (cli->use_oplocks) cli_process_oplock(cli); -- cgit From 0af00edf672eda7556f12745c80873376b85676f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jan 2000 14:41:20 +0000 Subject: I'm currently designing a new locking system (using a tdb database!) that will make us match NT semantics exactly and do away with the horrible fd multiplexing in smbd. this is some diag stuff to get me started. - added the ability to do read or write locks in clientgen.c - added a LOCK4 test to smbtorture. This produces a report on the server and its locking capabilities. For example, NT4 gives this: the same process cannot set overlapping write locks the same process can set overlapping read locks a different connection cannot set overlapping write locks a different connection can set overlapping read locks a different pid cannot set overlapping write locks a different pid can set overlapping read locks the same process can set the same read lock twice the same process cannot set the same write lock twice the same process cannot override a read lock with a write lock the same process can override a write lock with a read lock a different pid cannot override a write lock with a read lock the same process cannot coalesce read locks this server does strict write locking this server does strict read locking whereas Samba currently gives this: the same process can set overlapping write locks the same process can set overlapping read locks a different connection cannot set overlapping write locks a different connection can set overlapping read locks a different pid can set overlapping write locks a different pid can set overlapping read locks the same process can set the same read lock twice the same process can set the same write lock twice the same process can override a read lock with a write lock the same process can override a write lock with a read lock a different pid can override a write lock with a read lock the same process can coalesce read locks this server does strict write locking this server does strict read locking win95 gives this - I don't understand why! the same process cannot set overlapping write locks the same process cannot set overlapping read locks a different connection cannot set overlapping write locks a different connection cannot set overlapping read locks a different pid cannot set overlapping write locks a different pid cannot set overlapping read locks the same process cannot set the same read lock twice the same process cannot set the same write lock twice the same process cannot override a read lock with a write lock the same process cannot override a write lock with a read lock a different pid cannot override a write lock with a read lock the same process cannot coalesce read locks this server does strict write locking this server does strict read locking (This used to be commit 49637936b6e9478df248c4ef73d818870c73b597) --- source3/libsmb/clientgen.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3b6403fe73..bf610a7ff7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1344,7 +1344,8 @@ BOOL cli_close(struct cli_state *cli, int fnum) /**************************************************************************** lock a file ****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype) { char *p; int saved_timeout = cli->timeout; @@ -1360,7 +1361,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -1390,7 +1391,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti /**************************************************************************** unlock a file ****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +BOOL cli_unlock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype) { char *p; @@ -1405,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); -- cgit From 6bad53f758437938ee9b1cbdd34d1b74a1c522dd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Jan 2000 12:08:53 +0000 Subject: the lock routines now take a enumerated type for read/write locks, and we now don't pass the lock type at all for unlocks. I was surprised to discover that NT totally ignores the lock type in unlocks. It unlocks a matching write lock if there is one, otherwise it removes the first matching read lock. (This used to be commit 1bbc1ce18b8ccb92b5a78ee648539a591a452118) --- source3/libsmb/clientgen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bf610a7ff7..06a5e5427f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1345,7 +1345,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) lock a file ****************************************************************************/ BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, int locktype) + uint32 offset, uint32 len, int timeout, enum lock_type lock_type) { char *p; int saved_timeout = cli->timeout; @@ -1361,7 +1361,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); + CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -1392,7 +1392,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, unlock a file ****************************************************************************/ BOOL cli_unlock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, int locktype) + uint32 offset, uint32 len, int timeout) { char *p; @@ -1407,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); + CVAL(cli->outbuf,smb_vwv3) = 0; SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); -- cgit From 82af221e4a7e456f580f16bc5d2fd904fc018c96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 04:32:57 +0000 Subject: we now pass all byte range locking tests the last piece was to use a smb timeout slightly larger than the locking timeout in bloking locks to prevent a race (This used to be commit 1b54cb4a33a65e62c2e3189b78ef073869a60c75) --- source3/libsmb/clientgen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 06a5e5427f..1c9a2123cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1372,7 +1372,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, SIVAL(p, 6, len); cli_send_smb(cli); - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); if (!cli_receive_smb(cli)) { cli->timeout = saved_timeout; @@ -1391,8 +1391,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, /**************************************************************************** unlock a file ****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout) +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) { char *p; @@ -1408,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); CVAL(cli->outbuf,smb_vwv3) = 0; - SIVALS(cli->outbuf, smb_vwv4, timeout); + SIVALS(cli->outbuf, smb_vwv4, 0); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); -- cgit From 7bc1cc7e07991641d436b2c8a35b52663d4c5c05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 08:01:44 +0000 Subject: damn, Solaris already has a "enum lock_type" changed it to "enum brl_type" (This used to be commit 6b9ee7662c7afa70f6b20889e6b0ae1dcd677f9f) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1c9a2123cc..3497fb0f14 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1345,7 +1345,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) lock a file ****************************************************************************/ BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum lock_type lock_type) + uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { char *p; int saved_timeout = cli->timeout; -- cgit From 33157e9bfc154f9151993e66bc26b3b282aac11a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2000 11:09:32 +0000 Subject: fixed a formatting error (This used to be commit 10d9d81e8b7eba588526a5d479be74ce8f86fc55) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3497fb0f14..c510302301 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1293,7 +1293,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = smb_buf(cli->outbuf); pstrcpy(p,fname); - unix_to_dos(p,True); + unix_to_dos(p,True); p = skip_string(p,1); cli_send_smb(cli); -- cgit From 2768aecae653929d89d7cd402d953571fe51486e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 14:45:22 +0000 Subject: Defensive programming for cli_error(). Jeremy. (This used to be commit 94ed74d5b09d6f28b47b2855c4e4a1dc5c2108d3) --- source3/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c510302301..b1d8f8aa73 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2685,12 +2685,18 @@ void cli_shutdown(struct cli_state *cli) ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); + int flgs2; char rcls; int code; if (eclass) *eclass = 0; if (num ) *num = 0; + if (nt_rpc_error) *nt_rpc_error = 0; + + if(!cli || !cli->initialised || !cli->inbuf) + return EINVAL; + + flgs2 = SVAL(cli->inbuf,smb_flg2); if (nt_rpc_error) *nt_rpc_error = cli->nt_error; if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { -- cgit From f452de7ed622669ce203b58e5a528a0933da58ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 15:43:09 +0000 Subject: Correct for for core dump in smbpasswd with cli_errstr(). Jeremy.plit the test for NetBIOS name being *SMBSERVER. (This used to be commit 34b0e2acb050e384c132ddfb50ec84157fb430c6) --- source3/libsmb/clientgen.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b1d8f8aa73..0b669715b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2693,9 +2693,12 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ if (num ) *num = 0; if (nt_rpc_error) *nt_rpc_error = 0; - if(!cli || !cli->initialised || !cli->inbuf) + if(cli->initialised) return EINVAL; + if(!cli->inbuf) + return ENOMEM; + flgs2 = SVAL(cli->inbuf,smb_flg2); if (nt_rpc_error) *nt_rpc_error = cli->nt_error; @@ -3225,7 +3228,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) ****************************************************************************/ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip) + struct in_addr *pdest_ip) { struct nmb_name calling, called; @@ -3244,21 +3247,32 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char if (!cli_session_request(cli, &calling, &called)) { struct nmb_name smbservername; + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + /* * If the name wasn't *SMBSERVER then * try with *SMBSERVER if the first name fails. */ - cli_shutdown(cli); + if (nmb_name_equal(&called, &smbservername)) { - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + /* + * The name used was *SMBSERVER, don't bother with another name. + */ + + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ +with error %s.\n", desthost, cli_errstr(cli) )); + cli_shutdown(cli); + return False; + } + + cli_shutdown(cli); - if (!nmb_name_equal(&called, &smbservername) || - !cli_initialise(cli) || + if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) || !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n", - desthost)); + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ +name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From 9d59503d554fe66a674265c2036f01c236165963 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Feb 2000 21:52:35 +0000 Subject: Ooops. Fixed stupid typo with missing ! in cli error code. Jeremy. (This used to be commit 0babc4baea62aa40e8698ab88b3a95d514c001b6) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0b669715b9..d40bfc379a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2693,7 +2693,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ if (num ) *num = 0; if (nt_rpc_error) *nt_rpc_error = 0; - if(cli->initialised) + if(!cli->initialised) return EINVAL; if(!cli->inbuf) -- cgit From 74ca35e4eef8e758f37488a1128d462c21ce004c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Feb 2000 05:06:53 +0000 Subject: Not enough args to DEBUG statement. (This used to be commit 156f438bce607236b2d91c28f3dbe8559e048738) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d40bfc379a..32148a4e12 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -3261,7 +3261,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char */ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ -with error %s.\n", desthost, cli_errstr(cli) )); +with error %s.\n", desthost, "*SMBSERVER", cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From 9db96b7646aa36aa5b4ff309419235fe20bef78a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Feb 2000 02:02:33 +0000 Subject: lib/system.c: Fixed gcc warnings. nmbd/nmbd_processlogon.c: Use "True" and "False" instead of 1 and 0. Others - preparing for multiple pdu write code. Jeremy. (This used to be commit 9f879ec396230deba34fbe5e82d8a65f92137c54) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 32148a4e12..df3df0b4ba 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -3260,8 +3260,8 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char * The name used was *SMBSERVER, don't bother with another name. */ - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ -with error %s.\n", desthost, "*SMBSERVER", cli_errstr(cli) )); + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ +with error %s.\n", desthost, cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From 0f1eee5c7ac4031cd2a97524b1f65a24d0d618c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Feb 2000 22:25:25 +0000 Subject: client/client.c: libsmb/clientgen.c: Fixes for Win2k smbclient browsing. Other fixes implement smbpasswd -x user to delete users. Also allows swat to do the same. Jeremy. (This used to be commit 9f6ad046761adecafba59040baa3abc9f0959e65) --- source3/libsmb/clientgen.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index df3df0b4ba..8d7dbec859 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -600,7 +600,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; @@ -618,12 +618,16 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,0xFFFF); + /* + * Win2k needs a *smaller* buffer than 0xFFFF here - + * it returns "out of server memory" with 0xFFFF !!! JRA. + */ + SSVAL(p,2,0xFFE0); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFFF, /* data, length, maxlen */ + NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { -- cgit From 0958f44f17d05f78ddf6c25e97c317bf1b24da16 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Mar 2000 21:42:15 +0000 Subject: Fix from christoph.pfisterer@rwg.de for large directory listing to OS/2 server. Jeremy. (This used to be commit ce1c36541255b51ae429e530c0ebf016009ab84e) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d7dbec859..29c228ecfa 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2193,7 +2193,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); pstrcpy(param+12,mask); @@ -2203,7 +2203,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ pstrcpy(param+12,mask); DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", -- cgit From 2fa922611bf7160e2c1ce80c11b50006448bf98d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Apr 2000 13:55:53 +0000 Subject: finally got sick of the "extern int Client" code and the stupid assumption that we have one socket everywhere while doing so I discovered a few bugs! 1) the clientgen session retarget code if used from smbd or nmbd would cause a crash as it called close_sockets() which closed our main socket! fixed by removing close_sockets() completely - it is unnecessary 2) the caching in client_addr() and client_name() was bogus - it could easily get fooled and give the wrong result. fixed. 3) the retarget could could recurse, allowing an easy denial of service attack on nmbd. fixed. (This used to be commit 5937ab14d222696e40a3fc6f0e6a536f2d7305d3) --- source3/libsmb/clientgen.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 29c228ecfa..6472cf0380 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -88,10 +88,9 @@ static BOOL cli_send_smb(struct cli_state *cli) } } if (ret <= 0) { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", + DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); - close_sockets(); - exit(1); + return False; } nwritten += ret; } @@ -1516,11 +1515,11 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t if (size2 > block) { DEBUG(0,("server returned more than we wanted!\n")); - exit(1); + return -1; } if (mid >= issued) { DEBUG(0,("invalid mid from server!\n")); - exit(1); + return -1; } p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); @@ -2551,7 +2550,6 @@ retry: /* SESSION RETARGET */ putip((char *)&cli->dest_ip,cli->inbuf+4); - close_sockets(); cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); if (cli->fd == -1) return False; @@ -2561,7 +2559,18 @@ retry: set_socket_options(cli->fd,user_socket_options); /* Try again */ - return cli_session_request(cli, calling, called); + { + static int depth; + BOOL ret; + if (depth > 4) { + DEBUG(0,("Retarget recursion - failing\n")); + return False; + } + depth++; + ret = cli_session_request(cli, calling, called); + depth--; + return ret; + } } /* C. Hoch 9/14/95 End */ #ifdef WITH_SSL -- cgit From 858e63cab3b6a23692678d6eb03f9e48c3c08603 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Apr 2000 14:04:06 +0000 Subject: split clientgen.c into several parts the next step is splitting out the auth code, to make adding lukes NTLMSSP support easier (This used to be commit 10c5470835b43116ed48b3137c3b9cc867a20989) --- source3/libsmb/clientgen.c | 3160 +------------------------------------------- 1 file changed, 51 insertions(+), 3109 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6472cf0380..a3a2483bd5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,12 +22,9 @@ #define NO_SYSLOG #include "includes.h" -#include "trans2.h" extern int DEBUGLEVEL; -extern pstring user_socket_options; - static void cli_process_oplock(struct cli_state *cli); /* @@ -44,7 +41,7 @@ int cli_set_port(struct cli_state *cli, int port) /**************************************************************************** recv an smb ****************************************************************************/ -static BOOL cli_receive_smb(struct cli_state *cli) +BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; again: @@ -69,7 +66,7 @@ static BOOL cli_receive_smb(struct cli_state *cli) /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli) +BOOL cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; @@ -101,7 +98,7 @@ static BOOL cli_send_smb(struct cli_state *cli) /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ -static void cli_setup_packet(struct cli_state *cli) +void cli_setup_packet(struct cli_state *cli) { cli->rap_error = 0; cli->nt_error = 0; @@ -154,3142 +151,87 @@ static void cli_process_oplock(struct cli_state *cli) } -/***************************************************** - RAP error codes - a small start but will be extended. -*******************************************************/ - -struct -{ - int err; - char *message; -} rap_errmap[] = -{ - {5, "User has insufficient privilege" }, - {86, "The specified password is invalid" }, - {2226, "Operation only permitted on a Primary Domain Controller" }, - {2242, "The password of this user has expired." }, - {2243, "The password of this user cannot change." }, - {2244, "This password cannot be used now (password history conflict)." }, - {2245, "The password is shorter than required." }, - {2246, "The password of this user is too recent to change."}, - - /* these really shouldn't be here ... */ - {0x80, "Not listening on called name"}, - {0x81, "Not listening for calling name"}, - {0x82, "Called name not present"}, - {0x83, "Called name present, but insufficient resources"}, - - {0, NULL} -}; - /**************************************************************************** - return a description of an SMB error +initialise a client structure ****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) +struct cli_state *cli_initialise(struct cli_state *cli) { - return smb_errstr(cli->inbuf); -} - -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) -{ - static fstring error_message; - uint8 errclass; - uint32 errnum; - uint32 nt_rpc_error; - int i; - - /* - * Errors are of three kinds - smb errors, - * dealt with by cli_smb_errstr, NT errors, - * whose code is in cli.nt_error, and rap - * errors, whose error code is in cli.rap_error. - */ - - cli_error(cli, &errclass, &errnum, &nt_rpc_error); - - if (errclass != 0) - { - return cli_smb_errstr(cli); + if (!cli) { + cli = (struct cli_state *)malloc(sizeof(*cli)); + if (!cli) + return NULL; + ZERO_STRUCTP(cli); } - /* - * Was it an NT error ? - */ - - if (nt_rpc_error) - { - char *nt_msg = get_nt_error_msg(nt_rpc_error); - - if (nt_msg == NULL) - { - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); - } - else - { - fstrcpy(error_message, nt_msg); - } - - return error_message; + if (cli->initialised) { + cli_shutdown(cli); } - /* - * Must have been a rap error. - */ - - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + ZERO_STRUCTP(cli); - for (i = 0; rap_errmap[i].message != NULL; i++) + cli->port = 0; + cli->fd = -1; + cli->cnum = -1; + cli->pid = (uint16)getpid(); + cli->mid = 1; + cli->vuid = UID_FIELD_INVALID; + cli->protocol = PROTOCOL_NT1; + cli->timeout = 20000; /* Timeout is in milliseconds. */ + cli->bufsize = CLI_BUFFER_SIZE+4; + cli->max_xmit = cli->bufsize; + cli->outbuf = (char *)malloc(cli->bufsize); + cli->inbuf = (char *)malloc(cli->bufsize); + if (!cli->outbuf || !cli->inbuf) { - if (rap_errmap[i].err == cli->rap_error) - { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; -} - -/***************************************************************************** - Convert a character pointer in a cli_call_api() response to a form we can use. - This function contains code to prevent core dumps if the server returns - invalid data. -*****************************************************************************/ -static char *fix_char_ptr(unsigned int datap, unsigned int converter, - char *rdata, int rdrcnt) -{ - if (datap == 0) { /* turn NULL pointers into zero length strings */ - return ""; - } else { - unsigned int offset = datap - converter; - - if (offset >= rdrcnt) { - DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", - datap, converter, rdrcnt)); - return ""; - } else { - return &rdata[offset]; - } - } -} - -/**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, int trans, - char *name, int pipe_name_len, - int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) -{ - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; - char *outdata,*outparam; - char *p; - - this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ - this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,14+lsetup,0,True); - CVAL(cli->outbuf,smb_com) = trans; - SSVAL(cli->outbuf,smb_tid, cli->cnum); - cli_setup_packet(cli); - - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); - outdata = outparam+this_lparam; - - /* primary request */ - SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ - SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ - SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ - SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ - SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ - SSVAL(cli->outbuf,smb_flags,flags); /* flags */ - SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ - SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ - SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ - SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ - SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ - SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ - for (i=0;ioutbuf,smb_setup+i*2,setup[i]); - p = smb_buf(cli->outbuf); - if (trans==SMBtrans) { - memcpy(p,name, pipe_name_len + 1); /* name[] */ - } else { - *p++ = 0; /* put in a null smb_name */ - *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ - } - if (this_lparam) /* param[] */ - memcpy(outparam,param,this_lparam); - if (this_ldata) /* data[] */ - memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - - show_msg(cli->outbuf); - cli_send_smb(cli); - - if (this_ldata < ldata || this_lparam < lparam) { - /* receive interim response */ - if (!cli_receive_smb(cli) || - CVAL(cli->inbuf,smb_rcls) != 0) { - return(False); - } - - tot_data = this_ldata; - tot_param = this_lparam; - - while (tot_data < ldata || tot_param < lparam) { - this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ - this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - - set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); - CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; - - outparam = smb_buf(cli->outbuf); - outdata = outparam+this_lparam; - - /* secondary request */ - SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ - SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ - SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ - SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ - SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ - SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ - SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ - SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ - if (trans==SMBtrans2) - SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ - if (this_lparam) /* param[] */ - memcpy(outparam,param+tot_param,this_lparam); - if (this_ldata) /* data[] */ - memcpy(outdata,data+tot_data,this_ldata); - set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - - show_msg(cli->outbuf); - cli_send_smb(cli); - - tot_data += this_ldata; - tot_param += this_lparam; - } - } - - return(True); -} - - -/**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ -static BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) -{ - int total_data=0; - int total_param=0; - int this_data,this_param; - uint8 eclass; - uint32 ecode; - - *data_len = *param_len = 0; - - if (!cli_receive_smb(cli)) return False; - - show_msg(cli->inbuf); - - /* sanity check */ - if (CVAL(cli->inbuf,smb_com) != trans) { - DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", - CVAL(cli->inbuf,smb_com))); - return(False); - } - - /* - * An NT RPC pipe call can return ERRDOS, ERRmoredata - * to a trans call. This is not an error and should not - * be treated as such. - */ - - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); - } - - /* parse out the lengths */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - - /* allocate it */ - *data = Realloc(*data,total_data); - *param = Realloc(*param,total_param); - - while (1) { - this_data = SVAL(cli->inbuf,smb_drcnt); - this_param = SVAL(cli->inbuf,smb_prcnt); - - if (this_data + *data_len > total_data || - this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; - } - - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); - *data_len += this_data; - *param_len += this_param; - - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - - if (total_data <= *data_len && total_param <= *param_len) - break; - - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - /* sanity check */ - if (CVAL(cli->inbuf,smb_com) != trans) { - DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", - CVAL(cli->inbuf,smb_com))); - return(False); - } - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); - } - } - - return(True); -} - -/**************************************************************************** -Call a remote api on an arbitrary pipe. takes param, data and setup buffers. -****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count) -{ - if (pipe_name_len == 0) - pipe_name_len = strlen(pipe_name); - - cli_send_trans(cli, SMBtrans, - pipe_name, pipe_name_len, - 0,0, /* fid, flags */ - setup, setup_count, max_setup_count, - params, param_count, max_param_count, - data, data_count, max_data_count); - - return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); -} - -/**************************************************************************** -call a remote api -****************************************************************************/ -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) -{ - cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ - 0,0, /* fid, flags */ - NULL,0,0, /* Setup, length, max */ - param, prcnt, mprcnt, /* Params, length, max */ - data, drcnt, mdrcnt /* Data, length, max */ - ); - - return (cli_receive_trans(cli,SMBtrans, - rparam, rprcnt, - rdata, rdrcnt)); -} - - -/**************************************************************************** -perform a NetWkstaUserLogon -****************************************************************************/ -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - - memset(param, 0, sizeof(param)); - - /* send a SMBtrans command with api NetWkstaUserLogon */ - p = param; - SSVAL(p,0,132); /* api number */ - p += 2; - pstrcpy(p,"OOWb54WrLh"); - p = skip_string(p,1); - pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); - p = skip_string(p,1); - SSVAL(p,0,1); - p += 2; - pstrcpy(p,user); - strupper(p); - p += 21; - p++; - p += 15; - p++; - pstrcpy(p, workstation); - strupper(p); - p += 16; - SSVAL(p, 0, CLI_BUFFER_SIZE); - p += 2; - SSVAL(p, 0, CLI_BUFFER_SIZE); - p += 2; - - if (cli_api(cli, - param, PTR_DIFF(p,param),1024, /* param, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - cli->rap_error = SVAL(rparam,0); - p = rdata; - - if (cli->rap_error == 0) { - DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privileges = SVAL(p, 24); - fstrcpy(cli->eff_name,p+2); - } else { - DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); - } } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - return (cli->rap_error == 0); -} - -/**************************************************************************** -call a NetShareEnum - try and browse available connections on a host -****************************************************************************/ -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - int count = -1; - - /* now send a SMBtrans command with api RNetShareEnum */ - p = param; - SSVAL(p,0,0); /* api number */ - p += 2; - pstrcpy(p,"WrLeh"); - p = skip_string(p,1); - pstrcpy(p,"B13BWz"); - p = skip_string(p,1); - SSVAL(p,0,1); - /* - * Win2k needs a *smaller* buffer than 0xFFFF here - - * it returns "out of server memory" with 0xFFFF !!! JRA. - */ - SSVAL(p,2,0xFFE0); - p += 4; - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - int res = SVAL(rparam,0); - int converter=SVAL(rparam,2); - int i; - - if (res == 0 || res == ERRmoredata) { - count=SVAL(rparam,4); - p = rdata; - - for (i=0;i rdrcnt) continue; + memset(cli->outbuf, '\0', cli->bufsize); + memset(cli->inbuf, '\0', cli->bufsize); - stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + cli->initialised = 1; - dos_to_unix(sname, True); - dos_to_unix(cmnt, True); - fn(sname, stype, cmnt); - } - } - } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - - return(count > 0); + return cli; } - - - -static struct { - int prot; - char *name; - } -prots[] = - { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} - }; - - /**************************************************************************** - Send a session setup. The username is in UNIX character format and must be - converted to DOS codepage format before sending. If the password is in - plaintext, the same should be done. +shutdown a client structure ****************************************************************************/ - -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) +void cli_shutdown(struct cli_state *cli) { - char *p; - fstring pword, ntpword; - - if (cli->protocol < PROTOCOL_LANMAN1) - return True; - - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { - return False; - } - - if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { - /* Null session connect. */ - pword[0] = '\0'; - ntpword[0] = '\0'; - } else { - if ((cli->sec_mode & 2) && passlen != 24) { - /* - * Encrypted mode needed, and non encrypted password supplied. - */ - passlen = 24; - ntpasslen = 24; - fstrcpy(pword, pass); - unix_to_dos(pword,True); - fstrcpy(ntpword, ntpass);; - unix_to_dos(ntpword,True); - SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); - SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); - } else if ((cli->sec_mode & 2) && passlen == 24) { - /* - * Encrypted mode needed, and encrypted password supplied. - */ - memcpy(pword, pass, passlen); - if(ntpasslen == 24) { - memcpy(ntpword, ntpass, ntpasslen); - } else { - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } else { - /* - * Plaintext mode needed, assume plaintext supplied. - */ - fstrcpy(pword, pass); - unix_to_dos(pword,True); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } - - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { - fstrcpy(pword, ""); - passlen=1; - fstrcpy(ntpword, ""); - ntpasslen=1; - } - - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); - - if (cli->protocol < PROTOCOL_NT1) + if (cli->outbuf) { - set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,1); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); + free(cli->outbuf); } - else + if (cli->inbuf) { - set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,0); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpword,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,workgroup); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - pstrcpy(p,"Samba");p = skip_string(p,1); - set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - } - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - dos_to_unix(cli->server_os, True); - fstrcpy(cli->server_type, server_type); - dos_to_unix(cli->server_type, True); - fstrcpy(cli->server_domain, server_domain); - dos_to_unix(cli->server_domain, True); - } - - fstrcpy(cli->user_name, user); - dos_to_unix(cli->user_name, True); - - return True; -} - -/**************************************************************************** - Send a uloggoff. -*****************************************************************************/ - -BOOL cli_ulogoff(struct cli_state *cli) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBulogoffX; - cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - return CVAL(cli->inbuf,smb_rcls) == 0; -} - -/**************************************************************************** -send a tconX -****************************************************************************/ -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen) -{ - fstring fullshare, pword, dos_pword; - char *p; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - fstrcpy(cli->share, share); - - /* in user level security don't send a password now */ - if (cli->sec_mode & 1) { - passlen = 1; - pass = ""; - } - - if ((cli->sec_mode & 2) && *pass && passlen != 24) { - /* - * Non-encrypted passwords - convert to DOS codepage before encryption. - */ - passlen = 24; - fstrcpy(dos_pword,pass); - unix_to_dos(dos_pword,True); - SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); - } else { - if(!(cli->sec_mode & 2)) { - /* - * Non-encrypted passwords - convert to DOS codepage before using. - */ - fstrcpy(pword,pass); - unix_to_dos(pword,True); - } else { - memcpy(pword, pass, passlen); - } - } - - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); - unix_to_dos(fullshare, True); - strupper(fullshare); - - set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); - CVAL(cli->outbuf,smb_com) = SMBtconX; - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv3,passlen); - - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); - unix_to_dos(p,True); - - SCVAL(cli->inbuf,smb_rcls, 1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - fstrcpy(cli->dev, "A:"); - - if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); - } - - if (strcasecmp(share,"IPC$")==0) { - fstrcpy(cli->dev, "IPC"); - } - - /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && - smb_buflen(cli->inbuf) == 3) { - /* almost certainly win95 - enable bug fixes */ - cli->win95 = True; + free(cli->inbuf); } - - cli->cnum = SVAL(cli->inbuf,smb_tid); - return True; +#ifdef WITH_SSL + if (cli->fd != -1) + sslutil_disconnect(cli->fd); +#endif /* WITH_SSL */ + if (cli->fd != -1) + close(cli->fd); + memset(cli, 0, sizeof(*cli)); } /**************************************************************************** -send a tree disconnect +set socket options on a open connection ****************************************************************************/ -BOOL cli_tdis(struct cli_state *cli) +void cli_sockopt(struct cli_state *cli, char *options) { - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBtdis; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - return CVAL(cli->inbuf,smb_rcls) == 0; + set_socket_options(cli->fd, options); } /**************************************************************************** -rename a file +set the PID to use for smb messages. Return the old pid. ****************************************************************************/ -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) +uint16 cli_setpid(struct cli_state *cli, uint16 pid) { - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); - - CVAL(cli->outbuf,smb_com) = SMBmv; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,fname_src); - unix_to_dos(p,True); - p = skip_string(p,1); - *p++ = 4; - pstrcpy(p,fname_dst); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; + uint16 ret = cli->pid; + cli->pid = pid; + return ret; } -/**************************************************************************** -delete a file -****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, char *fname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1, 2 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBunlink; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,fname); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -create a directory -****************************************************************************/ -BOOL cli_mkdir(struct cli_state *cli, char *dname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0, 2 + strlen(dname),True); - - CVAL(cli->outbuf,smb_com) = SMBmkdir; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -remove a directory -****************************************************************************/ -BOOL cli_rmdir(struct cli_state *cli, char *dname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0, 2 + strlen(dname),True); - - CVAL(cli->outbuf,smb_com) = SMBrmdir; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - - - -/**************************************************************************** -open a file -****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,24,1 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBntcreateX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); - SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); - SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); - SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); - SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); - - p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2 + 1); -} - - -/**************************************************************************** -open a file -WARNING: if you open with O_WRONLY then getattrE won't work! -****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) -{ - char *p; - unsigned openfn=0; - unsigned accessmode=0; - - if (flags & O_CREAT) - openfn |= (1<<4); - if (!(flags & O_EXCL)) { - if (flags & O_TRUNC) - openfn |= (1<<1); - else - openfn |= (1<<0); - } - - accessmode = (share_mode<<4); - - if ((flags & O_ACCMODE) == O_RDWR) { - accessmode |= 2; - } else if ((flags & O_ACCMODE) == O_WRONLY) { - accessmode |= 1; - } - -#if defined(O_SYNC) - if ((flags & O_SYNC) == O_SYNC) { - accessmode |= (1<<14); - } -#endif /* O_SYNC */ - - if (share_mode == DENY_FCB) { - accessmode = 0xFF; - } - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,15,1 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBopenX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - SSVAL(cli->outbuf,smb_vwv3,accessmode); - SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv8,openfn); - - if (cli->use_oplocks) { - /* if using oplocks then ask for a batch oplock via - core and extended methods */ - CVAL(cli->outbuf,smb_flg) |= - FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; - SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); - } - - p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2); -} - - - - -/**************************************************************************** - close a file -****************************************************************************/ -BOOL cli_close(struct cli_state *cli, int fnum) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,3,0,True); - - CVAL(cli->outbuf,smb_com) = SMBclose; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVALS(cli->outbuf,smb_vwv1,-1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - - -/**************************************************************************** - lock a file -****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type) -{ - char *p; - int saved_timeout = cli->timeout; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0', smb_size); - - set_message(cli->outbuf,8,10,True); - - CVAL(cli->outbuf,smb_com) = SMBlockingX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0); - SIVALS(cli->outbuf, smb_vwv4, timeout); - SSVAL(cli->outbuf,smb_vwv6,0); - SSVAL(cli->outbuf,smb_vwv7,1); - - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - cli_send_smb(cli); - - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); - - if (!cli_receive_smb(cli)) { - cli->timeout = saved_timeout; - return False; - } - - cli->timeout = saved_timeout; - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** - unlock a file -****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,8,10,True); - - CVAL(cli->outbuf,smb_com) = SMBlockingX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); - - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - - - -/**************************************************************************** -issue a single SMBread and don't wait for a reply -****************************************************************************/ -static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,10,0,True); - - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - cli_send_smb(cli); -} - -/**************************************************************************** - read from a file -****************************************************************************/ -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) -{ - char *p; - int total = -1; - int issued=0; - int received=0; -/* - * There is a problem in this code when mpx is more than one. - * for some reason files can get corrupted when being read. - * Until we understand this fully I am serializing reads (one - * read/one reply) for now. JRA. - */ -#if 0 - int mpx = MAX(cli->max_mux-1, 1); -#else - int mpx = 1; -#endif - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int mid; - int blocks = (size + (block-1)) / block; - - if (size == 0) return 0; - - while (received < blocks) { - int size2; - - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, size-issued*block); - cli_issue_read(cli, fnum, offset+issued*block, size1, issued); - issued++; - } - - if (!cli_receive_smb(cli)) { - return total; - } - - received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; - size2 = SVAL(cli->inbuf, smb_vwv5); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } - - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; - } - - if (size2 > block) { - DEBUG(0,("server returned more than we wanted!\n")); - return -1; - } - if (mid >= issued) { - DEBUG(0,("invalid mid from server!\n")); - return -1; - } - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - - memcpy(buf+mid*block, p, size2); - - total = MAX(total, mid*block + size2); - } - - while (received < issued) { - cli_receive_smb(cli); - received++; - } - - return total; -} - - -/**************************************************************************** -issue a single SMBwrite and don't wait for a reply -****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, - size_t size, int i) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,12,size,True); - - CVAL(cli->outbuf,smb_com) = SMBwriteX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - - SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); - SSVAL(cli->outbuf,smb_vwv7,mode); - - SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); - SSVAL(cli->outbuf,smb_vwv10,size); - SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf, size); - - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - show_msg(cli->outbuf); - cli_send_smb(cli); -} - -/**************************************************************************** - write to a file - write_mode: 0x0001 disallow write cacheing - 0x0002 return bytes remaining - 0x0004 use raw named pipe protocol - 0x0008 start of message mode named pipe protocol -****************************************************************************/ -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size) -{ - int bwritten = 0; - int issued = 0; - int received = 0; - int mpx = MAX(cli->max_mux-1, 1); - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int blocks = (size + (block-1)) / block; - - while (received < blocks) { - - while ((issued - received < mpx) && (issued < blocks)) - { - int bsent = issued * block; - int size1 = MIN(block, size - bsent); - - cli_issue_write(cli, fnum, offset + bsent, - write_mode, - buf + bsent, - size1, issued); - issued++; - } - - if (!cli_receive_smb(cli)) - { - return bwritten; - } - - received++; - - if (CVAL(cli->inbuf,smb_rcls) != 0) - { - break; - } - - bwritten += SVAL(cli->inbuf, smb_vwv2); - } - - while (received < issued && cli_receive_smb(cli)) - { - received++; - } - - return bwritten; -} - - -/**************************************************************************** - write to a file using a SMBwrite and not bypassing 0 byte writes -****************************************************************************/ -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1) -{ - char *p; - ssize_t total = 0; - - do { - size_t size = MIN(size1, cli->max_xmit - 48); - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,5, 3 + size,True); - - CVAL(cli->outbuf,smb_com) = SMBwrite; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SSVAL(cli->outbuf,smb_vwv1,size); - SIVAL(cli->outbuf,smb_vwv2,offset); - SSVAL(cli->outbuf,smb_vwv4,0); - - p = smb_buf(cli->outbuf); - *p++ = 1; - SSVAL(p, 0, size); - memcpy(p+2, buf, size); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - size = SVAL(cli->inbuf,smb_vwv0); - if (size == 0) break; - - size1 -= size; - total += size; - } while (size1); - - return total; -} - - -/**************************************************************************** -do a SMBgetattrE call -****************************************************************************/ -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1,0,True); - - CVAL(cli->outbuf,smb_com) = SMBgetattrE; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fd); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - if (size) { - *size = IVAL(cli->inbuf, smb_vwv6); - } - - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv10); - } - - if (c_time) { - *c_time = make_unix_date3(cli->inbuf+smb_vwv0); - } - - if (a_time) { - *a_time = make_unix_date3(cli->inbuf+smb_vwv2); - } - - if (m_time) { - *m_time = make_unix_date3(cli->inbuf+smb_vwv4); - } - - return True; -} - - -/**************************************************************************** -do a SMBgetatr call -****************************************************************************/ -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0,strlen(fname)+2,True); - - CVAL(cli->outbuf,smb_com) = SMBgetatr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - if (size) { - *size = IVAL(cli->inbuf, smb_vwv3); - } - - if (t) { - *t = make_unix_date3(cli->inbuf+smb_vwv1); - } - - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv0); - } - - - return True; -} - - -/**************************************************************************** -do a SMBsetatr call -****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,8,strlen(fname)+4,True); - - CVAL(cli->outbuf,smb_com) = SMBsetatr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0, attr); - put_dos_date3(cli->outbuf,smb_vwv1, t); - - p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); - p = skip_string(p,1); - *p = 4; - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -send a qpathinfo call -****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - int count=8; - BOOL ret; - time_t (*date_fn)(void *); - - param_len = strlen(fname) + 7; - - memset(param, 0, param_len); - SSVAL(param, 0, SMB_INFO_STANDARD); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); - - do { - ret = (cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - ) && - cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)); - if (!ret) { - /* we need to work around a Win95 bug - sometimes - it gives ERRSRV/ERRerror temprarily */ - uint8 eclass; - uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); - if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); - } - } while (count-- && ret==False); - - if (!ret || !rdata || data_len < 22) { - return False; - } - - if (cli->win95) { - date_fn = make_unix_date; - } else { - date_fn = make_unix_date2; - } - - if (c_time) { - *c_time = date_fn(rdata+0); - } - if (a_time) { - *a_time = date_fn(rdata+4); - } - if (m_time) { - *m_time = date_fn(rdata+8); - } - if (size) { - *size = IVAL(rdata, 12); - } - if (mode) { - *mode = SVAL(rdata,l1_attrFile); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - -/**************************************************************************** -send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level -****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - - param_len = strlen(fname) + 7; - - memset(param, 0, param_len); - SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } - - if (!rdata || data_len < 22) { - return False; - } - - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; - } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; - } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; - } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; - } - if (mode) { - *mode = SVAL(rdata, 32); - } - if (size) { - *size = IVAL(rdata, 48); - } - if (ino) { - *ino = IVAL(rdata, 64); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - - -/**************************************************************************** -send a qfileinfo call -****************************************************************************/ -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QFILEINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - - /* if its a win95 server then fail this - win95 totally screws it - up */ - if (cli->win95) return False; - - param_len = 4; - - memset(param, 0, param_len); - SSVAL(param, 0, fnum); - SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } - - if (!rdata || data_len < 68) { - return False; - } - - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; - } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; - } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; - } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; - } - if (mode) { - *mode = SVAL(rdata, 32); - } - if (size) { - *size = IVAL(rdata, 48); - } - if (ino) { - *ino = IVAL(rdata, 64); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - - -/**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 -****************************************************************************/ -static int interpret_long_filename(int level,char *p,file_info *finfo) -{ - extern file_info def_finfo; - - if (finfo) - memcpy(finfo,&def_finfo,sizeof(*finfo)); - - switch (level) - { - case 1: /* OS/2 understands this */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+27); - dos_to_unix(finfo->name,True); - } - return(28 + CVAL(p,26)); - - case 2: /* this is what OS/2 uses mostly */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+31); - dos_to_unix(finfo->name,True); - } - return(32 + CVAL(p,30)); - - /* levels 3 and 4 are untested */ - case 3: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+33); - dos_to_unix(finfo->name,True); - } - return(SVAL(p,4)+4); - - case 4: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+37); - dos_to_unix(finfo->name,True); - } - return(SVAL(p,4)+4); - - case 260: /* NT uses this, but also accepts 2 */ - if (finfo) { - int ret = SVAL(p,0); - int namelen; - p += 4; /* next entry offset */ - p += 4; /* fileindex */ - - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; - p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; - p += 4; /* EA size */ - p += 2; /* short name len? */ - p += 24; /* short name? */ - StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); - dos_to_unix(finfo->name,True); - return(ret); - } - return(SVAL(p,0)); - } - - DEBUG(1,("Unknown long filename format %d\n",level)); - return(SVAL(p,0)); -} - - -/**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) -{ - int max_matches = 512; - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - int info_level = cli->protocol 200) { - DEBUG(0,("Error: Looping in FIND_NEXT??\n")); - break; - } - - param_len = 12+strlen(mask)+1; - - if (First) { - setup = TRANSACT2_FINDFIRST; - SSVAL(param,0,attribute); /* attribute */ - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,4+2); /* resume required + close on end */ - SSVAL(param,6,info_level); - SIVAL(param,8,0); - pstrcpy(param+12,mask); - } else { - setup = TRANSACT2_FINDNEXT; - SSVAL(param,0,ff_dir_handle); - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,info_level); - SIVAL(param,6,0); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - pstrcpy(param+12,mask); - - DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_lastname,mask)); - } - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, 0, - cli->max_xmit /* data, length, max */ - )) { - break; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - /* we need to work around a Win95 bug - sometimes - it gives ERRSRV/ERRerror temprarily */ - uint8 eclass; - uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); - if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); - continue; - } - - if (total_received == -1) total_received = 0; - - /* parse out some important return info */ - p = rparam; - if (First) { - ff_dir_handle = SVAL(p,0); - ff_searchcount = SVAL(p,2); - ff_eos = SVAL(p,4); - ff_lastname = SVAL(p,8); - } else { - ff_searchcount = SVAL(p,0); - ff_eos = SVAL(p,2); - ff_lastname = SVAL(p,6); - } - - if (ff_searchcount == 0) - break; - - /* point to the data bytes */ - p = rdata; - - /* we might need the lastname for continuations */ - if (ff_lastname > 0) { - switch(info_level) - { - case 260: - StrnCpy(mask,p+ff_lastname, - MIN(sizeof(mask)-1,data_len-ff_lastname)); - break; - case 1: - pstrcpy(mask,p + ff_lastname + 1); - break; - } - } else { - pstrcpy(mask,""); - } - - dos_to_unix(mask, True); - - /* and add them to the dirlist pool */ - dirlist = Realloc(dirlist,dirlist_len + data_len); - - if (!dirlist) { - DEBUG(0,("Failed to expand dirlist\n")); - break; - } - - /* put in a length for the last entry, to ensure we can chain entries - into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); - SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); - - /* grab the data for later use */ - memcpy(dirlist+dirlist_len,p,data_len); - dirlist_len += data_len; - - total_received += ff_searchcount; - - if (rdata) free(rdata); rdata = NULL; - if (rparam) free(rparam); rparam = NULL; - - DEBUG(3,("received %d entries (eos=%d)\n", - ff_searchcount,ff_eos)); - - if (ff_searchcount > 0) loop_count = 0; - - First = False; - } - - for (p=dirlist,i=0;i= sizeof(fstring)-1) { - DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); - return False; - } - - SSVAL(p,0,214); /* SamOEMChangePassword command. */ - p += 2; - pstrcpy(p, "zsT"); - p = skip_string(p,1); - pstrcpy(p, "B516B16"); - p = skip_string(p,1); - pstrcpy(p,user); - p = skip_string(p,1); - SSVAL(p,0,532); - p += 2; - - param_len = PTR_DIFF(p,param); - - /* - * Get the Lanman hash of the old password, we - * use this as the key to make_oem_passwd_hash(). - */ - memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - fstrcpy(upper_case_old_pw, old_password); - unix_to_dos(upper_case_old_pw,True); - strupper(upper_case_old_pw); - E_P16((uchar *)upper_case_old_pw, old_pw_hash); - - pstrcpy(dos_new_password, new_password); - unix_to_dos(dos_new_password, True); - - if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) - return False; - - /* - * Now place the old password hash in the data. - */ - memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - fstrcpy(upper_case_new_pw, new_password); - unix_to_dos(upper_case_new_pw,True); - strupper(upper_case_new_pw); - - E_P16((uchar *)upper_case_new_pw, new_pw_hash); - - E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); - - data_len = 532; - - if (cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ - 0,0, /* fid, flags */ - NULL,0,0, /* setup, length, max */ - param,param_len,2, /* param, length, max */ - data,data_len,0 /* data, length, max */ - ) == False) { - DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", - user )); - return False; - } - - if (cli_receive_trans(cli,SMBtrans, - &rparam, &rprcnt, - &rdata, &rdrcnt)) { - if (rparam) - cli->rap_error = SVAL(rparam,0); - } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - - return (cli->rap_error == 0); -} - -/**************************************************************************** -send a negprot command -****************************************************************************/ -BOOL cli_negprot(struct cli_state *cli) -{ - char *p; - int numprots; - int plength; - - memset(cli->outbuf,'\0',smb_size); - - /* setup the protocol strings */ - for (plength=0,numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) - plength += strlen(prots[numprots].name)+2; - - set_message(cli->outbuf,0,plength,True); - - p = smb_buf(cli->outbuf); - for (numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) { - *p++ = 2; - pstrcpy(p,prots[numprots].name); - unix_to_dos(p,True); - p += strlen(p) + 1; - } - - CVAL(cli->outbuf,smb_com) = SMBnegprot; - cli_setup_packet(cli); - - CVAL(smb_buf(cli->outbuf),0) = 2; - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (CVAL(cli->inbuf,smb_rcls) != 0 || - ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { - return(False); - } - - cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - - - if (cli->protocol >= PROTOCOL_NT1) { - /* NT protocol */ - cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); - cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); - cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); - cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); - cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); - cli->serverzone *= 60; - /* this time arrives in real GMT */ - cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & 1) { - cli->readbraw_supported = True; - cli->writebraw_supported = True; - } - } else if (cli->protocol >= PROTOCOL_LANMAN1) { - cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); - cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); - cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10); - cli->serverzone *= 60; - /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); - cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); - cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - } else { - /* the old core protocol */ - cli->sec_mode = 0; - cli->serverzone = TimeDiff(time(NULL)); - } - - cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); - - return True; -} - - -/**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 -****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called) -{ - char *p; - int len = 4; - /* send a session request (RFC 1002) */ - - memcpy(&(cli->calling), calling, sizeof(*calling)); - memcpy(&(cli->called ), called , sizeof(*called )); - - /* put in the destination name */ - p = cli->outbuf+len; - name_mangle(cli->called .name, p, cli->called .name_type); - len += name_len(p); - - /* and my name */ - p = cli->outbuf+len; - name_mangle(cli->calling.name, p, cli->calling.name_type); - len += name_len(p); - - /* setup the packet length */ - _smb_setlen(cli->outbuf,len); - CVAL(cli->outbuf,0) = 0x81; - -#ifdef WITH_SSL -retry: -#endif /* WITH_SSL */ - - cli_send_smb(cli); - DEBUG(5,("Sent session request\n")); - - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,0) == 0x84) { - /* C. Hoch 9/14/95 Start */ - /* For information, here is the response structure. - * We do the byte-twiddling to for portability. - struct RetargetResponse{ - unsigned char type; - unsigned char flags; - int16 length; - int32 ip_addr; - int16 port; - }; - */ - int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); - /* SESSION RETARGET */ - putip((char *)&cli->dest_ip,cli->inbuf+4); - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); - if (cli->fd == -1) - return False; - - DEBUG(3,("Retargeted\n")); - - set_socket_options(cli->fd,user_socket_options); - - /* Try again */ - { - static int depth; - BOOL ret; - if (depth > 4) { - DEBUG(0,("Retarget recursion - failing\n")); - return False; - } - depth++; - ret = cli_session_request(cli, calling, called); - depth--; - return ret; - } - } /* C. Hoch 9/14/95 End */ - -#ifdef WITH_SSL - if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if (!sslutil_fd_is_ssl(cli->fd)){ - if (sslutil_connect(cli->fd) == 0) - goto retry; - } - } -#endif /* WITH_SSL */ - - if (CVAL(cli->inbuf,0) != 0x82) { - /* This is the wrong place to put the error... JRA. */ - cli->rap_error = CVAL(cli->inbuf,4); - return False; - } - return(True); -} - - -/**************************************************************************** -open the client sockets -****************************************************************************/ -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) -{ - extern struct in_addr ipzero; - - fstrcpy(cli->desthost, host); - - if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { - return False; - } - if (ip) *ip = cli->dest_ip; - } else { - cli->dest_ip = *ip; - } - - if (cli->port == 0) cli->port = 139; /* Set to default */ - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli->port, cli->timeout); - if (cli->fd == -1) - return False; - - set_socket_options(cli->fd,user_socket_options); - - return True; -} - - -/**************************************************************************** -initialise a client structure -****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) -{ - if (!cli) { - cli = (struct cli_state *)malloc(sizeof(*cli)); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - } - - if (cli->initialised) { - cli_shutdown(cli); - } - - ZERO_STRUCTP(cli); - - cli->port = 0; - cli->fd = -1; - cli->cnum = -1; - cli->pid = (uint16)getpid(); - cli->mid = 1; - cli->vuid = UID_FIELD_INVALID; - cli->protocol = PROTOCOL_NT1; - cli->timeout = 20000; /* Timeout is in milliseconds. */ - cli->bufsize = CLI_BUFFER_SIZE+4; - cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); - if (!cli->outbuf || !cli->inbuf) - { - return False; - } - - memset(cli->outbuf, '\0', cli->bufsize); - memset(cli->inbuf, '\0', cli->bufsize); - - cli->initialised = 1; - - return cli; -} - -/**************************************************************************** -shutdown a client structure -****************************************************************************/ -void cli_shutdown(struct cli_state *cli) -{ - if (cli->outbuf) - { - free(cli->outbuf); - } - if (cli->inbuf) - { - free(cli->inbuf); - } -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ - if (cli->fd != -1) - close(cli->fd); - memset(cli, 0, sizeof(*cli)); -} - - -/**************************************************************************** - return error codes for the last packet - returns 0 if there was no error and the best approx of a unix errno - otherwise - - for 32 bit "warnings", a return code of 0 is expected. - -****************************************************************************/ -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) -{ - int flgs2; - char rcls; - int code; - - if (eclass) *eclass = 0; - if (num ) *num = 0; - if (nt_rpc_error) *nt_rpc_error = 0; - - if(!cli->initialised) - return EINVAL; - - if(!cli->inbuf) - return ENOMEM; - - flgs2 = SVAL(cli->inbuf,smb_flg2); - if (nt_rpc_error) *nt_rpc_error = cli->nt_error; - - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* 32 bit error codes detected */ - uint32 nt_err = IVAL(cli->inbuf,smb_rcls); - if (num) *num = nt_err; - DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - - switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; - } - - /* for all other cases - a default code */ - return EINVAL; - } - - rcls = CVAL(cli->inbuf,smb_rcls); - code = SVAL(cli->inbuf,smb_err); - if (rcls == 0) return 0; - - if (eclass) *eclass = rcls; - if (num ) *num = code; - - if (rcls == ERRDOS) { - switch (code) { - case ERRbadfile: return ENOENT; - case ERRbadpath: return ENOTDIR; - case ERRnoaccess: return EACCES; - case ERRfilexists: return EEXIST; - case ERRrename: return EEXIST; - case ERRbadshare: return EBUSY; - case ERRlock: return EBUSY; - } - } - if (rcls == ERRSRV) { - switch (code) { - case ERRbadpw: return EPERM; - case ERRaccess: return EACCES; - case ERRnoresource: return ENOMEM; - case ERRinvdevice: return ENODEV; - case ERRinvnetname: return ENODEV; - } - } - /* for other cases */ - return EINVAL; -} - -/**************************************************************************** -set socket options on a open connection -****************************************************************************/ -void cli_sockopt(struct cli_state *cli, char *options) -{ - set_socket_options(cli->fd, options); -} - -/**************************************************************************** -set the PID to use for smb messages. Return the old pid. -****************************************************************************/ -uint16 cli_setpid(struct cli_state *cli, uint16 pid) -{ - uint16 ret = cli->pid; - cli->pid = pid; - return ret; -} - -/**************************************************************************** -re-establishes a connection -****************************************************************************/ -BOOL cli_reestablish_connection(struct cli_state *cli) -{ - struct nmb_name calling; - struct nmb_name called; - fstring dest_host; - fstring share; - fstring dev; - BOOL do_tcon = False; - int oldfd = cli->fd; - - if (!cli->initialised || cli->fd == -1) - { - DEBUG(3,("cli_reestablish_connection: not connected\n")); - return False; - } - - /* copy the parameters necessary to re-establish the connection */ - - if (cli->cnum != 0) - { - fstrcpy(share, cli->share); - fstrcpy(dev , cli->dev); - do_tcon = True; - } - - memcpy(&called , &(cli->called ), sizeof(called )); - memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->full_dest_host_name); - - DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - nmb_namestr(&calling), nmb_namestr(&called), - inet_ntoa(cli->dest_ip), - cli->user_name, cli->domain)); - - cli->fd = -1; - - if (cli_establish_connection(cli, - dest_host, &cli->dest_ip, - &calling, &called, - share, dev, False, do_tcon)) { - if (cli->fd != oldfd) { - if (dup2(cli->fd, oldfd) == oldfd) { - close(cli->fd); - } - } - return True; - } - return False; -} - -/**************************************************************************** -establishes a connection right up to doing tconX, reading in a password. -****************************************************************************/ -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon) -{ - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); - - /* establish connection */ - - if ((!cli->initialised)) - { - return False; - } - - if (cli->fd == -1) - { - if (!cli_connect(cli, dest_host, dest_ip)) - { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(calling), inet_ntoa(*dest_ip))); - return False; - } - } - - if (!cli_session_request(cli, calling, called)) - { - DEBUG(1,("failed session request\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (!cli_negprot(cli)) - { - DEBUG(1,("failed negprot\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (cli->pwd.cleartext || cli->pwd.null_pwd) - { - fstring passwd; - int pass_len; - - if (cli->pwd.null_pwd) - { - /* attempt null session */ - passwd[0] = 0; - pass_len = 1; - } - else - { - /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); - pass_len = strlen(passwd); - } - - /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, - passwd, pass_len, - NULL, 0, - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)passwd, strlen(passwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else - { - /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; - unsigned char lm_sess_pwd[24]; - - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); - - /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - } - } - - if (do_shutdown) - cli_shutdown(cli); - - return True; -} - - -/**************************************************************************** - cancel a print job - ****************************************************************************/ -int cli_printjob_del(struct cli_state *cli, int job) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt, ret = -1; - pstring param; - - memset(param,'\0',sizeof(param)); - - p = param; - SSVAL(p,0,81); /* DosPrintJobDel() */ - p += 2; - pstrcpy(p,"W"); - p = skip_string(p,1); - pstrcpy(p,""); - p = skip_string(p,1); - SSVAL(p,0,job); - p += 2; - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) { /* return data, length */ - ret = SVAL(rparam,0); - } - - if (rparam) free(rparam); - if (rdata) free(rdata); - - return ret; -} - - -/**************************************************************************** -call fn() on each entry in a print queue -****************************************************************************/ -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt, rprcnt; - pstring param; - int result_code=0; - int i = -1; - - memset(param,'\0',sizeof(param)); - - p = param; - SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ - p += 2; - pstrcpy(p,"zWrLeh"); /* parameter description? */ - p = skip_string(p,1); - pstrcpy(p,"WWzWWDDzz"); /* returned data format */ - p = skip_string(p,1); - pstrcpy(p,cli->share); /* name of queue */ - p = skip_string(p,1); - SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ - SSVAL(p,2,1000); /* size of bytes of returned data buffer */ - p += 4; - pstrcpy(p,""); /* subformat */ - p = skip_string(p,1); - - DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) { /* return data, length */ - int converter; - result_code = SVAL(rparam,0); - converter = SVAL(rparam,2); /* conversion factor */ - - if (result_code == 0) { - struct print_job_info job; - - p = rdata; - - for (i = 0; i < SVAL(rparam,4); ++i) { - job.id = SVAL(p,0); - job.priority = SVAL(p,2); - fstrcpy(job.user, - fix_char_ptr(SVAL(p,4), converter, - rdata, rdrcnt)); - job.t = make_unix_date3(p + 12); - job.size = IVAL(p,16); - fstrcpy(job.name,fix_char_ptr(SVAL(p,24), - converter, - rdata, rdrcnt)); - fn(&job); - p += 28; - } - } - } - - /* If any parameters or data were returned, free the storage. */ - if(rparam) free(rparam); - if(rdata) free(rdata); - - return i; -} - -/**************************************************************************** -check for existance of a dir -****************************************************************************/ -BOOL cli_chkpath(struct cli_state *cli, char *path) -{ - pstring path2; - char *p; - - safe_strcpy(path2,path,sizeof(pstring)); - trim_string(path2,NULL,"\\"); - if (!*path2) *path2 = '\\'; - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,4 + strlen(path2),True); - SCVAL(cli->outbuf,smb_com,SMBchkpth); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - p = smb_buf(cli->outbuf); - *p++ = 4; - safe_strcpy(p,path2,strlen(path2)); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - - -/**************************************************************************** -start a message sequence -****************************************************************************/ -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp) -{ - char *p; - - /* send a SMBsendstrt command */ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendstrt; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,username); - unix_to_dos(p,True); - p = skip_string(p,1); - *p++ = 4; - pstrcpy(p,host); - unix_to_dos(p,True); - p = skip_string(p,1); - - set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - *grp = SVAL(cli->inbuf,smb_vwv0); - - return True; -} - - -/**************************************************************************** -send a message -****************************************************************************/ -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,len+3,True); - CVAL(cli->outbuf,smb_com) = SMBsendtxt; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,grp); - - p = smb_buf(cli->outbuf); - *p = 1; - SSVAL(p,1,len); - memcpy(p+3,msg,len); - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - -/**************************************************************************** -end a message -****************************************************************************/ -BOOL cli_message_end(struct cli_state *cli, int grp) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendend; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - - SSVAL(cli->outbuf,smb_vwv0,grp); - - cli_setup_packet(cli); - - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - - -/**************************************************************************** -query disk space -****************************************************************************/ -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBdskattr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); - *total = SVAL(cli->inbuf,smb_vwv0); - *avail = SVAL(cli->inbuf,smb_vwv3); - - return True; -} - -/**************************************************************************** - Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. -****************************************************************************/ - -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip) -{ - struct nmb_name calling, called; - - make_nmb_name(&calling, srchost, 0x0); - - /* - * If the called name is an IP address - * then use *SMBSERVER immediately. - */ - - if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20); - else - make_nmb_name(&called, desthost, 0x20); - - if (!cli_session_request(cli, &calling, &called)) { - struct nmb_name smbservername; - - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); - - /* - * If the name wasn't *SMBSERVER then - * try with *SMBSERVER if the first name fails. - */ - - if (nmb_name_equal(&called, &smbservername)) { - - /* - * The name used was *SMBSERVER, don't bother with another name. - */ - - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ -with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - - cli_shutdown(cli); - - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ -name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - } - - return True; -} -- cgit From 693ffb8466ada58ecc59fde754ba79fc6f51528d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 May 2000 02:23:41 +0000 Subject: Added sys_fork() and sys_getpid() functions to stop the overhead of doing a system call every time we want to just get our pid. Jeremy. (This used to be commit 148628b616b5c29ba6340d65fc3ddbcabba6e67a) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a3a2483bd5..32564aaf82 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -172,7 +172,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->port = 0; cli->fd = -1; cli->cnum = -1; - cli->pid = (uint16)getpid(); + cli->pid = (uint16)sys_getpid(); cli->mid = 1; cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; -- cgit From 098b7b378c72632d8c3df0b795ac1e4c5dbfb04a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 3 Jul 2000 04:24:31 +0000 Subject: first pass at merging rpcclient from TNG to HEAD. You can get a semi-connection and a rpcclient prompt, but no functionality there yet. Will be a few more days on that. These files changed only with the addition of some support functions from TNG --jerry (This used to be commit a04ea15f723e559db3c60bed03318cc7be851f69) --- source3/libsmb/clientgen.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 32564aaf82..c6f24c5e80 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -150,6 +150,23 @@ static void cli_process_oplock(struct cli_state *cli) cli->outbuf = oldbuf; } +/**************************************************************************** +initialise a client structure +****************************************************************************/ +void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) +{ + /* copy_nt_creds(&cli->usr, usr); */ + safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); + safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); + cli->ntlmssp_flags = usr->ntlmssp_flags; + cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; + + DEBUG(10,("cli_init_creds: user %s domain %s flgs: %x\nntlmssp_cli_flgs:%x\n", + cli->user_name, cli->domain, + cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); +} + /**************************************************************************** initialise a client structure -- 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/libsmb/clientgen.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c6f24c5e80..8d9fcb61d6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -203,6 +203,12 @@ struct cli_state *cli_initialise(struct cli_state *cli) return False; } + if ((cli->mem_ctx = talloc_init()) == NULL) { + free(cli->outbuf); + free(cli->inbuf); + return False; + } + memset(cli->outbuf, '\0', cli->bufsize); memset(cli->inbuf, '\0', cli->bufsize); @@ -224,6 +230,10 @@ void cli_shutdown(struct cli_state *cli) { free(cli->inbuf); } + + if (cli->mem_ctx) + talloc_destroy(cli->mem_ctx); + #ifdef WITH_SSL if (cli->fd != -1) sslutil_disconnect(cli->fd); -- cgit From 6f58dd587124c8b85fc62177b26129aaea5819b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Nov 2000 00:59:18 +0000 Subject: Ok - fixed a bug in our levelII oplock code. We need to break a level II on a byte range lock (write lock only, but Win2k breaks on read lock also so I do the same) - if you think about why, this is obvious. Also fixed our client code to do level II oplocks, if requested, and fixed the code where we would assume the client wanted level II if it advertised itself as being level II capable - it may not want that. Jeremy. (This used to be commit 213cd0b5192307cd4b0026cae94b2f52fb1b0c02) --- source3/libsmb/clientgen.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d9fcb61d6..8d9e2f034f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -121,14 +121,20 @@ static void cli_process_oplock(struct cli_state *cli) char *oldbuf = cli->outbuf; pstring buf; int fnum; + unsigned char level; fnum = SVAL(cli->inbuf,smb_vwv2); + level = CVAL(cli->inbuf,smb_vwv3+1); /* damn, we really need to keep a record of open files so we can detect a oplock break and a close crossing on the wire. for now this swallows the errors */ if (fnum == 0) return; + /* Ignore level II break to none's. */ + if (level == OPLOCKLEVEL_NONE) + return; + cli->outbuf = buf; memset(buf,'\0',smb_size); @@ -140,7 +146,10 @@ static void cli_process_oplock(struct cli_state *cli) SSVAL(buf,smb_vwv0,0xFF); SSVAL(buf,smb_vwv1,0); SSVAL(buf,smb_vwv2,fnum); - SSVAL(buf,smb_vwv3,2); /* oplock break ack */ + if (cli->use_level_II_oplocks) + SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ + else + SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ SIVAL(buf,smb_vwv4,0); /* timoeut */ SSVAL(buf,smb_vwv6,0); /* unlockcount */ SSVAL(buf,smb_vwv7,0); /* lockcount */ -- cgit From 369f5fd1d7a6e6298bc3cbe01e3aaed0106f6cf4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Dec 2000 01:02:11 +0000 Subject: Fixed memory leaks in lsa_XX calls. Fixed memory leaks in smbcacls. Merged in fixes from appliance-head and 2.2. Fixed multiple connection.tdb open problem. Jeremy. (This used to be commit 0a40bc83e14c69a09948ec09bb6fc5026c4f4c14) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d9e2f034f..1938049806 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -209,13 +209,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->inbuf = (char *)malloc(cli->bufsize); if (!cli->outbuf || !cli->inbuf) { - return False; + return NULL; } if ((cli->mem_ctx = talloc_init()) == NULL) { free(cli->outbuf); free(cli->inbuf); - return False; + return NULL; } memset(cli->outbuf, '\0', cli->bufsize); -- cgit From 6492d6b2f6a2743f5e794447911cbbba7e031d5d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 08:09:06 +0000 Subject: initial client side unicode support (needed for netapp filer) I've currently got this code disabled by default as it is incomplete. You enable it by setting a USE_UNICODE environment variable. Once the support is complete this check will be removed and the CAP_UNICODE capability bit will be the sole determination of whether the client library code uses unicode right now I have converted session_setup and tconx. I will do more fns over the next few days. see clistr.c for the new client side string interface. Luckily it tends to make the code smaller and neater while adding unicode support. (This used to be commit e1a04e621f1c28d8e6e543d43741ca0272e2237f) --- source3/libsmb/clientgen.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1938049806..d7649074db 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -95,19 +95,35 @@ BOOL cli_send_smb(struct cli_state *cli) return True; } +int cli_use_unicode = 0; + /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ void cli_setup_packet(struct cli_state *cli) { + static int initialised; + + /* the USE_UNICODE check will be deleted once our client side unicode + support is complete (tridge) */ + if (!initialised) { + initialised = 1; + if (getenv("USE_UNICODE")) cli_use_unicode = 1; + } + cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { + uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,0x1); + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + if (cli_use_unicode && cli->capabilities & CAP_UNICODE) { + flags2 |= FLAGS2_UNICODE_STRINGS; + } + SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From 8acf5e04482cb43734fbb786f8d363ee3bfff652 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:45:50 +0000 Subject: - neater setting of bcc - converted cli_rename and cli_unlink (This used to be commit 0a8992e224b7a3d90d45b13d73fa8a6f155efa79) --- source3/libsmb/clientgen.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d7649074db..c25e71ff3d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -127,6 +127,13 @@ void cli_setup_packet(struct cli_state *cli) } } +/**************************************************************************** +setup the bcc length of the packet from a pointer to the end of the data +****************************************************************************/ +void cli_setup_bcc(struct cli_state *cli, void *p) +{ + set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); +} /**************************************************************************** -- cgit From a8ab9840786b8376283743de8eef861d382b3171 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Feb 2001 03:40:20 +0000 Subject: the unicode conversion of our client code is complete enough to be enabled by default you can disable it by setting the environment variable CLI_FORCE_ASCII (This used to be commit 4d59c08c5e6f54c0d6ced7650750cb987e77b6c9) --- source3/libsmb/clientgen.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c25e71ff3d..8d4a025fcc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -95,22 +95,11 @@ BOOL cli_send_smb(struct cli_state *cli) return True; } -int cli_use_unicode = 0; - /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ void cli_setup_packet(struct cli_state *cli) { - static int initialised; - - /* the USE_UNICODE check will be deleted once our client side unicode - support is complete (tridge) */ - if (!initialised) { - initialised = 1; - if (getenv("USE_UNICODE")) cli_use_unicode = 1; - } - cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); @@ -120,7 +109,7 @@ void cli_setup_packet(struct cli_state *cli) uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli_use_unicode && cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) { flags2 |= FLAGS2_UNICODE_STRINGS; } SSVAL(cli->outbuf,smb_flg2, flags2); -- cgit From 5ffe6fd4cd1afd28d2c595b278bd3be9f5df70f2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 4 May 2001 07:28:41 +0000 Subject: Zero fnum when initialising a cli_state. (This used to be commit 5a387f59c441d355fe4535eae5c2c924ae9dd451) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d4a025fcc..8e00bca82a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -233,6 +233,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, '\0', cli->bufsize); memset(cli->inbuf, '\0', cli->bufsize); + cli->nt_pipe_fnum = 0; + cli->initialised = 1; return cli; -- cgit From e324e21457b232acb13a06fa5a4b8f363b3dec7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Jun 2001 08:26:15 +0000 Subject: added a oplock break handler hook to the client code, this allows for more complete testing of oplocks from smbtorture and would also be essential if a client app ever really did want to use oplocks properly (This used to be commit 3d4a3bfacd9ef225aeaab801e5a216d12814b60a) --- source3/libsmb/clientgen.c | 54 ++++++---------------------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8e00bca82a..e9f55850ac 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -25,7 +25,6 @@ extern int DEBUGLEVEL; -static void cli_process_oplock(struct cli_state *cli); /* * Change the port number used to call on @@ -53,7 +52,11 @@ BOOL cli_receive_smb(struct cli_state *cli) CVAL(cli->inbuf,smb_com) == SMBlockingX && SVAL(cli->inbuf,smb_vwv6) == 0 && SVAL(cli->inbuf,smb_vwv7) == 0) { - if (cli->use_oplocks) cli_process_oplock(cli); + if (cli->oplock_handler) { + int fnum = SVAL(cli->inbuf,smb_vwv2); + unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); + if (!cli->oplock_handler(cli, fnum, level)) return False; + } /* try to prevent loops */ CVAL(cli->inbuf,smb_com) = 0xFF; goto again; @@ -125,51 +128,6 @@ void cli_setup_bcc(struct cli_state *cli, void *p) } -/**************************************************************************** -process an oplock break request from the server -****************************************************************************/ -static void cli_process_oplock(struct cli_state *cli) -{ - char *oldbuf = cli->outbuf; - pstring buf; - int fnum; - unsigned char level; - - fnum = SVAL(cli->inbuf,smb_vwv2); - level = CVAL(cli->inbuf,smb_vwv3+1); - - /* damn, we really need to keep a record of open files so we - can detect a oplock break and a close crossing on the - wire. for now this swallows the errors */ - if (fnum == 0) return; - - /* Ignore level II break to none's. */ - if (level == OPLOCKLEVEL_NONE) - return; - - cli->outbuf = buf; - - memset(buf,'\0',smb_size); - set_message(buf,8,0,True); - - CVAL(buf,smb_com) = SMBlockingX; - SSVAL(buf,smb_tid, cli->cnum); - cli_setup_packet(cli); - SSVAL(buf,smb_vwv0,0xFF); - SSVAL(buf,smb_vwv1,0); - SSVAL(buf,smb_vwv2,fnum); - if (cli->use_level_II_oplocks) - SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ - else - SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ - SIVAL(buf,smb_vwv4,0); /* timoeut */ - SSVAL(buf,smb_vwv6,0); /* unlockcount */ - SSVAL(buf,smb_vwv7,0); /* lockcount */ - - cli_send_smb(cli); - - cli->outbuf = oldbuf; -} /**************************************************************************** initialise a client structure @@ -219,6 +177,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); + cli->oplock_handler = cli_oplock_ack; + if (!cli->outbuf || !cli->inbuf) { return NULL; -- cgit From 9f08cea054e7c2a3fd3b32d9c6711a269704d20b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 6 Aug 2001 02:18:40 +0000 Subject: Cleaned up error handling in cli_initialise() to fix a memleak found by Claudia Moroder (This used to be commit b5373f4b59cfe1cffe915e5d4eb29ed83fe99ba6) --- source3/libsmb/clientgen.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e9f55850ac..79fa224e8f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -180,24 +180,28 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->oplock_handler = cli_oplock_ack; if (!cli->outbuf || !cli->inbuf) - { - return NULL; - } + goto error; - if ((cli->mem_ctx = talloc_init()) == NULL) { - free(cli->outbuf); - free(cli->inbuf); - return NULL; - } + if ((cli->mem_ctx = talloc_init()) == NULL) + goto error; - memset(cli->outbuf, '\0', cli->bufsize); - memset(cli->inbuf, '\0', cli->bufsize); + memset(cli->outbuf, 0, cli->bufsize); + memset(cli->inbuf, 0, cli->bufsize); cli->nt_pipe_fnum = 0; cli->initialised = 1; return cli; + + /* Clean up after malloc() error */ + + error: + + safe_free(cli->inbuf); + safe_free(cli->outbuf); + + return NULL; } /**************************************************************************** -- cgit From a6234ad6f297611bcd00f67d388de532d1a6874f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 6 Aug 2001 23:29:25 +0000 Subject: Fixed another possible memleak in cli_initialise() (This used to be commit 4c9f010a1eef81addfea0315bef81570bc604f8a) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 79fa224e8f..ba852dea52 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -152,11 +152,14 @@ initialise a client structure ****************************************************************************/ struct cli_state *cli_initialise(struct cli_state *cli) { + BOOL alloced_cli = False; + if (!cli) { cli = (struct cli_state *)malloc(sizeof(*cli)); if (!cli) return NULL; ZERO_STRUCTP(cli); + alloced_cli = True; } if (cli->initialised) { @@ -201,6 +204,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) safe_free(cli->inbuf); safe_free(cli->outbuf); + if (alloced_cli) + safe_free(cli); + return NULL; } -- cgit From 2ccfea3de7b2b7dc0be2438c3adb3f7be82a2dfc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:00:33 +0000 Subject: A rewrite of the error handling in the libsmb client code. I've separated out the error handling into a bunch of separate functions rather than all being handled in one big function. Fetch error codes from the last received packet: void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num); uint32 cli_nt_error(struct cli_state *); Convert errors to UNIX errno values: int cli_errno_from_dos(uint8 eclass, uint32 num); int cli_errno_from_nt(uint32 status); int cli_errno(struct cli_state *cli); Detect different kinds of errors: BOOL cli_is_dos_error(struct cli_state *cli); BOOL cli_is_nt_error(struct cli_state *cli); BOOL cli_is_error(struct cli_state *cli); This also means we now support CAP_STATUS32 as we can decode and understand NT errors instead of just DOS errors. Yay! Ported a whole bunch of files in libsmb to use this new API instead of the just the DOS error. (This used to be commit 6dbdb0d813f3c7ab20b38baa1223b0b479aadec9) --- source3/libsmb/clientgen.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ba852dea52..5ddfa48ac0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,6 @@ setup basics in a outgoing packet void cli_setup_packet(struct cli_state *cli) { cli->rap_error = 0; - cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); -- cgit From 464237cdb8d4f4c4c93d9cf24f38f2720ea99b9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2001 20:11:09 +0000 Subject: fixed handling of 139/445 in clients (This used to be commit 22b372f8a7996a19bebb8cdb411df999cffa32a4) --- source3/libsmb/clientgen.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5ddfa48ac0..b3933f41e0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,10 +31,8 @@ extern int DEBUGLEVEL; */ int cli_set_port(struct cli_state *cli, int port) { - if (port > 0) - cli->port = port; - - return cli->port; + cli->port = port; + return port; } /**************************************************************************** -- cgit From e8e98c9ea0690e3acf1126b50882e59e1056c7b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 08:19:43 +0000 Subject: converted smbd to use NTSTATUS by default major changes include: - added NSTATUS type - added automatic mapping between dos and nt error codes - changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT() these calls auto-translate to the client error code system - got rid of the cached error code and the writebmpx code We eventually will need to also: - get rid of BOOL, so we don't lose error info - replace all ERROR_DOS() calls with ERROR_NT() calls but that is too much for one night (This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518) --- source3/libsmb/clientgen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b3933f41e0..87c8348853 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,6 +112,9 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_UNICODE) { flags2 |= FLAGS2_UNICODE_STRINGS; } + if (cli->capabilities & CAP_STATUS32) { + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From bcbd75f7add425ebee760ddbd2e80a1d4a51e619 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 03:33:37 +0000 Subject: move to SAFE_FREE() (This used to be commit 48fc6a6cd52e01b287030fbbf0aa08a6814c5e11) --- source3/libsmb/clientgen.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 87c8348853..79757947b4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -201,11 +201,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) error: - safe_free(cli->inbuf); - safe_free(cli->outbuf); + SAFE_FREE(cli->inbuf); + SAFE_FREE(cli->outbuf); if (alloced_cli) - safe_free(cli); + SAFE_FREE(cli); return NULL; } @@ -215,14 +215,8 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - if (cli->outbuf) - { - free(cli->outbuf); - } - if (cli->inbuf) - { - free(cli->inbuf); - } + SAFE_FREE(cli->outbuf); + SAFE_FREE(cli->inbuf); if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); -- 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/libsmb/clientgen.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 79757947b4..62b46a7904 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -23,9 +23,6 @@ #include "includes.h" - -extern int DEBUGLEVEL; - /* * Change the port number used to call on */ @@ -248,4 +245,3 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) cli->pid = pid; return ret; } - -- cgit From 81f56139b6964ddbe2c03232475f87f474136490 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Oct 2001 07:42:52 +0000 Subject: initial kerberos/ADS/SPNEGO support in libsmb and smbclient. To activate you need to: - install krb5 libraries - run configure - build smbclient - run kinit to get a TGT - run smbclient with the -k option to choose kerberos auth (This used to be commit d33057585644e1337bac743e25ed7653bfb39eef) --- source3/libsmb/clientgen.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 62b46a7904..b5eddd5644 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,6 +112,10 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } + if (cli->use_spnego) { + /* once we have NTLMSSP we can enable this unconditionally */ + flags2 |= FLAGS2_EXTENDED_SECURITY; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -215,15 +219,17 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + data_blob_free(cli->secblob); + if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); #ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); + if (cli->fd != -1) + sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ if (cli->fd != -1) - close(cli->fd); + close(cli->fd); memset(cli, 0, sizeof(*cli)); } -- cgit From 9f7cb41f11c0d2fc09104f6998f75c59bc363b26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Oct 2001 04:49:42 +0000 Subject: added NTLMSSP authentication to libsmb. It seems to work well so I have enabled it by default if the server supports it. Let me know if this breaks anything. Choose kerberos with the -k flag to smbclient, otherwise it will use SPNEGO/NTLMSSP/NTLM (This used to be commit 076aa97bee54d182288d9e93ae160ae22a5f7757) --- source3/libsmb/clientgen.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b5eddd5644..25dc070024 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,10 +112,7 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } - if (cli->use_spnego) { - /* once we have NTLMSSP we can enable this unconditionally */ - flags2 |= FLAGS2_EXTENDED_SECURITY; - } + flags2 |= FLAGS2_EXTENDED_SECURITY; SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From b728042334f67738fd1a6fdd03e619bdb78fe06a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Oct 2001 08:54:19 +0000 Subject: added basic NTLMSSP support in smbd. This is still quite rough, and loses things like username mapping. I wanted to get this in then discuss it a bit to see how we want to split up the existing session setup code (This used to be commit b74fda69bf23207c26d8b2af23910d8f2eb89875) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 25dc070024..ed0bc6481e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -216,7 +216,7 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); - data_blob_free(cli->secblob); + data_blob_free(&cli->secblob); if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); -- cgit From 4ccdb15532ef707dea44e2c7316e2a3334abab86 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Oct 2001 06:48:35 +0000 Subject: a quick fix to get rpcclient working again. This just disables NTLMSSP in cli_establish_connection() What we really need to do is kill off the pwd_cache code. It is horrible, and assumes the challenge comes in the negprot reply. (This used to be commit 3f919b4360b3bfcc133f7d88bc5177e9d93f2db2) --- source3/libsmb/clientgen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ed0bc6481e..ec8d2e2bfc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,7 +112,9 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } - flags2 |= FLAGS2_EXTENDED_SECURITY; + if (cli->use_spnego) { + flags2 |= FLAGS2_EXTENDED_SECURITY; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -179,6 +181,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; + cli->use_spnego = True; if (!cli->outbuf || !cli->inbuf) goto error; -- cgit From 2fc8e32ad342e3285e0d30a3a102e06ec4af5199 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 01:52:34 +0000 Subject: Parionia to ensure people don't install libsmb based programs setuid root. libsmb has not been written to be setuid, with things like LIBSMB_PROG allowing all sort of fun and games. Andrew Bartlett (This used to be commit 0c8e9339d8238de92e9146d04091694b62874c33) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ec8d2e2bfc..d509924a26 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -154,6 +154,12 @@ struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; + /* Check the effective uid - make sure we are not setuid */ + if (is_setuid_root()) { + DEBUG(0,("libsmb based programs must *NOT* be setuid root.\n")); + return NULL; + } + if (!cli) { cli = (struct cli_state *)malloc(sizeof(*cli)); if (!cli) -- cgit From 742dc2313c951f85ff66f0a8121790d0e291a19c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Nov 2001 04:15:36 +0000 Subject: Removed the "reestablish" code. Tridge - scream if this was needed.... Jeremy. (This used to be commit e6afe40f85d7dbe79322c82dac735d901e7e71df) --- source3/libsmb/clientgen.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d509924a26..d3623ad94e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -62,26 +62,19 @@ BOOL cli_receive_smb(struct cli_state *cli) } /**************************************************************************** - send an smb to a fd and re-establish if necessary + send an smb to a fd. ****************************************************************************/ + BOOL cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; ssize_t ret; - BOOL reestablished=False; len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) { - if (cli_reestablish_connection(cli)) { - reestablished = True; - nwritten=0; - continue; - } - } if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); -- cgit From 641f3070ab59f5fb681ccedb692de2ef7d9d90db Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 Nov 2001 05:58:51 +0000 Subject: Close the socket and set the file descriptor to -1 if there was a socket error in cli_receive_smb() and cli_send_smb(). (This used to be commit bedd9c821521dad46df50e8b31e4a58bb0a9a604) --- source3/libsmb/clientgen.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d3623ad94e..133408dff4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -58,6 +58,13 @@ BOOL cli_receive_smb(struct cli_state *cli) } } + /* If the server is not responding, note that now */ + + if (!ret) { + close(cli->fd); + cli->fd = -1; + } + return ret; } @@ -76,6 +83,8 @@ BOOL cli_send_smb(struct cli_state *cli) while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { + close(cli->fd); + cli->fd = -1; DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); return False; -- cgit From e734163ac472f64457ec4bcfd3e9bd364ee91c6c Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 21 Nov 2001 11:04:49 +0000 Subject: One more patch from Tom Jansen. Hope I didn't break the tree :-) (This used to be commit 6d7c0f0bb4cbfdcd9a83416345432e07556f6cfc) --- source3/libsmb/clientgen.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 133408dff4..0f1fa2e42e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -38,6 +38,10 @@ recv an smb BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; + + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) return False; + again: ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); @@ -78,6 +82,9 @@ BOOL cli_send_smb(struct cli_state *cli) size_t nwritten=0; ssize_t ret; + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) return False; + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { -- cgit From a71f3f66a1b47a70e402c4d82736f376449b923c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Nov 2001 02:35:37 +0000 Subject: Add a new torture test to extract a NT->DOS error map from an NT member of a samba domain. The PDC must be running a special authenticaion module that spits out NT errors based on username. Andrew Bartlett (This used to be commit adc7a6048c13342b79b6228beafb5142c50f318d) --- source3/libsmb/clientgen.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0f1fa2e42e..0e09388803 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -198,6 +198,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->oplock_handler = cli_oplock_ack; cli->use_spnego = True; + /* Set the CLI_FORCE_DOSERR environment variable to test + client routines using DOS errors instead of STATUS32 + ones. This intended only as a temporary hack. */ + if (getenv("CLI_FORCE_DOSERR")) { + cli->force_dos_errors = True; + } + if (!cli->outbuf || !cli->inbuf) goto error; -- cgit From 701ecfc7a0a944844cadfd0b2c19f104ab7984b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Nov 2001 03:29:20 +0000 Subject: prevent a memory leak of cli structures (This used to be commit 911c57403bd116405876e73913ad73efd15f659b) --- source3/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0e09388803..610af9cc23 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -217,6 +217,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->nt_pipe_fnum = 0; cli->initialised = 1; + cli->allocated = alloced_cli; return cli; @@ -238,6 +239,7 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { + BOOL allocated; SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); @@ -252,7 +254,11 @@ void cli_shutdown(struct cli_state *cli) #endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); - memset(cli, 0, sizeof(*cli)); + allocated = cli->allocated; + ZERO_STRUCTP(cli); + if (allocated) { + free(cli); + } } -- cgit From d6823366b881612234ab0655adb11c594f864c4a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2002 19:10:25 +0000 Subject: Same fix as went into 2.2 (I'm waiting for jerry to finish some code). Jeremy. (This used to be commit 01ff6ce4963e1daff019f2b936cef218e1c93f67) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 610af9cc23..022046ceb2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -57,7 +57,7 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!cli->oplock_handler(cli, fnum, level)) return False; } /* try to prevent loops */ - CVAL(cli->inbuf,smb_com) = 0xFF; + SCVAL(cli->inbuf,smb_com,0xFF); goto again; } } -- cgit From 7c822ae3fff114d796ab18a0ff0fb8abde560659 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jan 2002 00:54:37 +0000 Subject: Name another talloc. (This used to be commit 9d62f25f5d3c25d71d8b87801084d42ae9b66f8c) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 022046ceb2..50f9a7dc81 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -208,7 +208,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init()) == NULL) + if ((cli->mem_ctx = talloc_init_named("cli based talloc")) == NULL) goto error; memset(cli->outbuf, 0, cli->bufsize); -- 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/libsmb/clientgen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 50f9a7dc81..7d6258b24a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. SMB client generic functions Copyright (C) Andrew Tridgell 1994-1998 -- cgit From cd76214b15246553284ca43441780d49cf2f5819 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 1 Mar 2002 02:54:04 +0000 Subject: Another comment fix for mirmir (This used to be commit 7412890adc8f3dfddfabba545003715816e262bc) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7d6258b24a..ba7a327344 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -138,7 +138,7 @@ void cli_setup_bcc(struct cli_state *cli, void *p) /**************************************************************************** -initialise a client structure +initialise credentials of a client structure ****************************************************************************/ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { -- 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/libsmb/clientgen.c | 61 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 13 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ba7a327344..c9500ead5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,6 +31,41 @@ int cli_set_port(struct cli_state *cli, int port) return port; } +/**************************************************************************** + read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. +****************************************************************************/ + +static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +{ + BOOL ret; + + for(;;) + { + ret = receive_smb(fd, buffer, timeout); + + if (!ret) + { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} + + /**************************************************************************** recv an smb ****************************************************************************/ @@ -72,7 +107,7 @@ BOOL cli_receive_smb(struct cli_state *cli) } /**************************************************************************** - send an smb to a fd. + Send an smb to a fd. ****************************************************************************/ BOOL cli_send_smb(struct cli_state *cli) @@ -82,31 +117,33 @@ BOOL cli_send_smb(struct cli_state *cli) ssize_t ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; + + cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { - close(cli->fd); - cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", - (int)len,(int)ret)); + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); return False; } nwritten += ret; } - return True; } /**************************************************************************** -setup basics in a outgoing packet + Setup basics in a outgoing packet. ****************************************************************************/ + void cli_setup_packet(struct cli_state *cli) { - cli->rap_error = 0; + cli->rap_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); @@ -123,6 +160,8 @@ void cli_setup_packet(struct cli_state *cli) if (cli->use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } + if (cli->sign_info.use_smb_signing) + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -247,10 +286,6 @@ void cli_shutdown(struct cli_state *cli) if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); allocated = cli->allocated; -- 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/libsmb/clientgen.c | 144 ++++++++++++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 55 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c9500ead5d..793dd19644 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -32,49 +32,48 @@ int cli_set_port(struct cli_state *cli, int port) } /**************************************************************************** - read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. + Read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. ****************************************************************************/ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { - BOOL ret; - - for(;;) - { - ret = receive_smb(fd, buffer, timeout); - - if (!ret) - { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); - return ret; - } - - /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; - } - show_msg(buffer); - return ret; -} + BOOL ret; + + for(;;) { + ret = receive_smb(fd, buffer, timeout); + if (!ret) { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} /**************************************************************************** -recv an smb + Recv an smb. ****************************************************************************/ + BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; again: ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); @@ -151,34 +150,32 @@ void cli_setup_packet(struct cli_state *cli) uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; - } - if (cli->capabilities & CAP_STATUS32) { + if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; - } - if (cli->use_spnego) { + if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - } - if (cli->sign_info.use_smb_signing) + if (cli->sign_info.use_smb_signing + || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } /**************************************************************************** -setup the bcc length of the packet from a pointer to the end of the data + Setup the bcc length of the packet from a pointer to the end of the data. ****************************************************************************/ + void cli_setup_bcc(struct cli_state *cli, void *p) { set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } - - /**************************************************************************** -initialise credentials of a client structure + Initialise credentials of a client structure. ****************************************************************************/ + void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ @@ -193,10 +190,10 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); } - /**************************************************************************** -initialise a client structure + Initialise a client structure. ****************************************************************************/ + struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; @@ -215,9 +212,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) alloced_cli = True; } - if (cli->initialised) { - cli_shutdown(cli); - } + if (cli->initialised) + cli_close_connection(cli); ZERO_STRUCTP(cli); @@ -234,7 +230,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - cli->use_spnego = True; + if (lp_use_spnego()) { + cli->use_spnego = True; + } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 @@ -243,6 +241,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->force_dos_errors = True; } + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.negotiated_smb_signing = True; + if (!cli->outbuf || !cli->inbuf) goto error; @@ -273,43 +275,75 @@ struct cli_state *cli_initialise(struct cli_state *cli) } /**************************************************************************** -shutdown a client structure + Close a client connection and free the memory without destroying cli itself. ****************************************************************************/ -void cli_shutdown(struct cli_state *cli) + +void cli_close_connection(struct cli_state *cli) { - BOOL allocated; SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); data_blob_free(&cli->secblob); - if (cli->mem_ctx) + if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); + cli->mem_ctx = NULL; + } if (cli->fd != -1) close(cli->fd); - allocated = cli->allocated; + cli->fd = -1; +} + +/**************************************************************************** + Shutdown a client structure. +****************************************************************************/ + +void cli_shutdown(struct cli_state *cli) +{ + BOOL allocated = cli->allocated; + cli_close_connection(cli); ZERO_STRUCTP(cli); if (allocated) { free(cli); } } - /**************************************************************************** -set socket options on a open connection + Set socket options on a open connection. ****************************************************************************/ + void cli_sockopt(struct cli_state *cli, char *options) { set_socket_options(cli->fd, options); } /**************************************************************************** -set the PID to use for smb messages. Return the old pid. + Set the PID to use for smb messages. Return the old pid. ****************************************************************************/ + uint16 cli_setpid(struct cli_state *cli, uint16 pid) { uint16 ret = cli->pid; cli->pid = pid; return ret; } + +/**************************************************************************** +Send a keepalive packet to the server +****************************************************************************/ +BOOL cli_send_keepalive(struct cli_state *cli) +{ + if (cli->fd == -1) { + DEBUG(3, ("cli_send_keepalive: fd == -1\n")); + return False; + } + if (!send_keepalive(cli->fd)) { + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error sending keepalive packet to client.\n")); + return False; + } + return True; +} + -- cgit From 5cec60b31b63821ebc35f0a3f02b96329a08387d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 01:41:20 +0000 Subject: Added error string for server timeout on client call. Jeremy. (This used to be commit 28d2eb934318818a3b0527e391987ea139dbf4a3) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 793dd19644..156de42836 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -69,6 +69,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -100,6 +101,7 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!ret) { close(cli->fd); cli->fd = -1; + cli->smb_read_error = smb_read_error; } return ret; -- cgit From 88fad685d4c0e123ab0f85d8b081ae770569218e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 02:11:35 +0000 Subject: Tidy up client error processing. Jeremy. (This used to be commit aea64f1c300b1ec5ec1c5d637f456f025ec12821) --- source3/libsmb/clientgen.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 156de42836..4a102097ce 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,9 +22,10 @@ #include "includes.h" -/* - * Change the port number used to call on - */ +/**************************************************************************** + Change the port number used to call on. +****************************************************************************/ + int cli_set_port(struct cli_state *cli, int port) { cli->port = port; @@ -96,13 +97,13 @@ BOOL cli_receive_smb(struct cli_state *cli) } } - /* If the server is not responding, note that now */ + /* If the server is not responding, note that now */ - if (!ret) { - close(cli->fd); - cli->fd = -1; + if (!ret) { cli->smb_read_error = smb_read_error; - } + close(cli->fd); + cli->fd = -1; + } return ret; } @@ -130,7 +131,8 @@ BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); + DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", + (int)len,(int)ret, strerror(errno) )); return False; } nwritten += ret; @@ -232,16 +234,14 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - if (lp_use_spnego()) { + if (lp_use_spnego()) cli->use_spnego = True; - } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ - if (getenv("CLI_FORCE_DOSERR")) { + if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - } /* A way to attempt to force SMB signing */ if (getenv("CLI_FORCE_SMB_SIGNING")) @@ -295,6 +295,7 @@ void cli_close_connection(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); cli->fd = -1; + cli->smb_read_error = 0; } /**************************************************************************** @@ -306,9 +307,8 @@ void cli_shutdown(struct cli_state *cli) BOOL allocated = cli->allocated; cli_close_connection(cli); ZERO_STRUCTP(cli); - if (allocated) { + if (allocated) free(cli); - } } /**************************************************************************** @@ -348,4 +348,3 @@ BOOL cli_send_keepalive(struct cli_state *cli) } return True; } - -- cgit From 8147df0b6b4674670e70b45c603e8323e5c61c33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 06:50:38 +0000 Subject: Cope with rw errors and timeout to peer. Jeremy. (This used to be commit d8d351eb01ea7c84828dbc96224d7b13d643b558) --- source3/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4a102097ce..2236d8508d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -100,7 +100,7 @@ BOOL cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (!ret) { - cli->smb_read_error = smb_read_error; + cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; } @@ -131,6 +131,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return False; @@ -295,7 +296,7 @@ void cli_close_connection(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); cli->fd = -1; - cli->smb_read_error = 0; + cli->smb_rw_error = 0; } /**************************************************************************** -- cgit From ebc7fd0a3c3cf7f199cf89f82f1457ddd2cf8686 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Oct 2002 21:30:06 +0000 Subject: Added cli_set_timeout() call. Jeremy. (This used to be commit 9225054179b6642ae8be790d35e6590aefa46dd3) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2236d8508d..28480043b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,6 +22,17 @@ #include "includes.h" +/**************************************************************************** + Change the timeout (in milliseconds). +****************************************************************************/ + +unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout) +{ + unsigned int old_timeout = cli->timeout; + cli->timeout = timeout; + return old_timeout; +} + /**************************************************************************** Change the port number used to call on. ****************************************************************************/ -- cgit From ef8bd7c4f7ae8192ea05db070962ecf0ff3615f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Dec 2002 20:21:31 +0000 Subject: Forward port the change to talloc_init() to make all talloc contexts named. Ensure we can query them. Jeremy. (This used to be commit 09a218a9f6fb0bd922940467bf8500eb4f1bcf84) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 28480043b9..c843d49d27 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -262,7 +262,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init_named("cli based talloc")) == NULL) + if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL) goto error; memset(cli->outbuf, 0, cli->bufsize); -- 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/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c843d49d27..ed1286d627 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -327,7 +327,7 @@ void cli_shutdown(struct cli_state *cli) Set socket options on a open connection. ****************************************************************************/ -void cli_sockopt(struct cli_state *cli, char *options) +void cli_sockopt(struct cli_state *cli, const char *options) { set_socket_options(cli->fd, options); } -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libsmb/clientgen.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ed1286d627..9598f4ac96 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -114,9 +114,14 @@ BOOL cli_receive_smb(struct cli_state *cli) cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; + return ret; } - return ret; + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + return False; + }; + return True; } /**************************************************************************** @@ -246,8 +251,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - if (lp_use_spnego()) - cli->use_spnego = True; + + cli->use_spnego = lp_client_use_spnego(); + + cli->capabilities = CAP_UNICODE | CAP_STATUS32; /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 @@ -255,9 +262,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) - cli->sign_info.negotiated_smb_signing = True; + if (lp_client_signing()) + cli->sign_info.allow_smb_signing = True; if (!cli->outbuf || !cli->inbuf) goto error; -- cgit From 892599fb92b6158e86a3934c8f2045ee457f38e3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 12:01:47 +0000 Subject: Merge from HEAD: A much better SMB signing module, that allows for mulitple signing algorithms and correctly backs down from signing when the server cannot sign the reply. This also attempts to enable SMB signing on NTLMSSP connections, but I don't know what NTLMSSP flags to set yet. This would allow 'client use signing' to be set by default, for server compatability. (A seperate option value should be provided for mandetory signing, which would not back down). Andrew Bartlett (This used to be commit 1c87be7a3d127201a6ab78d22d17c971af16b86b) --- source3/libsmb/clientgen.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9598f4ac96..3cae643c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -177,9 +177,6 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - if (cli->sign_info.use_smb_signing - || cli->sign_info.temp_smb_signing) - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -200,8 +197,8 @@ void cli_setup_bcc(struct cli_state *cli, void *p) void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ - safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); - safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + fstrcpy(cli->domain , usr->domain); + fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); cli->ntlmssp_flags = usr->ntlmssp_flags; cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; @@ -262,6 +259,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; + /* initialise signing */ + cli_null_set_signing(cli); + if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -303,6 +303,7 @@ void cli_close_connection(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + cli_free_signing_context(cli); data_blob_free(&cli->secblob); if (cli->mem_ctx) { @@ -314,6 +315,7 @@ void cli_close_connection(struct cli_state *cli) close(cli->fd); cli->fd = -1; cli->smb_rw_error = 0; + } /**************************************************************************** -- cgit From ec2b31b7e31c4cdd9f187b329e4f26466ba9e748 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 12:02:51 +0000 Subject: Parinoia fixes from HEAD - malloc() some extra room after the allocated buffer size. (This used to be commit 27ec538eca0905e1f749de4c49cc2555c5932d5c) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3cae643c38..d969193089 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -245,8 +245,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); + cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); + cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->use_spnego = lp_client_use_spnego(); -- cgit From 7238bf5f40e16360439e028fa7607a5a28e02965 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 15:54:17 +0000 Subject: This is the netlogon schannel client code. Try a rpcclient -S pdc -U% -c "samlogon user password" and it should work with the schannel. Needs testing against platforms different from NT4SP6. Volker (This used to be commit eaef0d8aeff1aa5a067679be3f17e08d7434e1e8) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d969193089..81b3bbcab5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -275,6 +275,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->inbuf, 0, cli->bufsize); cli->nt_pipe_fnum = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; -- cgit From 1e2147fc0f677914fb2e3168b4fd4d7ddb4b9867 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 13:00:39 +0000 Subject: Merge SMB signing, cli buffer clobber and NTLMSSP signing tweaks from HEAD. (This used to be commit c6c4f69b8ddc500890a65829e1b9fb7a3e9839e9) --- source3/libsmb/clientgen.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81b3bbcab5..81cb61d757 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -118,7 +118,10 @@ BOOL cli_receive_smb(struct cli_state *cli) } if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; return False; }; return True; @@ -259,9 +262,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - /* initialise signing */ - cli_null_set_signing(cli); - if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -274,6 +274,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); + /* just becouse we over-allocate, doesn't mean it's right to use it */ + clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); + clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); + + /* initialise signing */ + cli_null_set_signing(cli); + cli->nt_pipe_fnum = 0; cli->saved_netlogon_pipe_fnum = 0; -- cgit From 402fbc518a5489b33f1c5eafb8e6acb9ee5addbd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 May 2003 00:46:43 +0000 Subject: spelling (This used to be commit 865c11275685c85124b506c9bbd2a8bde2e760b9) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81cb61d757..8d4e8a266c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -274,7 +274,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); - /* just becouse we over-allocate, doesn't mean it's right to use it */ + /* just because we over-allocate, doesn't mean it's right to use it */ clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); -- 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/libsmb/clientgen.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d4e8a266c..93fa94c1db 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -203,12 +203,9 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) fstrcpy(cli->domain , usr->domain); fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); - cli->ntlmssp_flags = usr->ntlmssp_flags; - cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; - DEBUG(10,("cli_init_creds: user %s domain %s flgs: %x\nntlmssp_cli_flgs:%x\n", - cli->user_name, cli->domain, - cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); + DEBUG(10,("cli_init_creds: user %s domain %s\n", + cli->user_name, cli->domain)); } /**************************************************************************** @@ -287,6 +284,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->initialised = 1; cli->allocated = alloced_cli; + cli->pipe_idx = -1; + return cli; /* Clean up after malloc() error */ @@ -302,18 +301,51 @@ struct cli_state *cli_initialise(struct cli_state *cli) return NULL; } +/**************************************************************************** +close the session +****************************************************************************/ + +void cli_nt_session_close(struct cli_state *cli) +{ + if (cli->ntlmssp_pipe_state) { + ntlmssp_client_end(&cli->ntlmssp_pipe_state); + } + + cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; + cli->pipe_idx = -1; +} + +/**************************************************************************** +close the NETLOGON session holding the session key for NETSEC +****************************************************************************/ + +void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) +{ + if (cli->saved_netlogon_pipe_fnum != 0) { + cli_close(cli, cli->saved_netlogon_pipe_fnum); + cli->saved_netlogon_pipe_fnum = 0; + } +} + /**************************************************************************** Close a client connection and free the memory without destroying cli itself. ****************************************************************************/ void cli_close_connection(struct cli_state *cli) { + cli_nt_session_close(cli); + cli_nt_netlogon_netsec_session_close(cli); + SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); data_blob_free(&cli->secblob); + if (cli->ntlmssp_pipe_state) + ntlmssp_client_end(&cli->ntlmssp_pipe_state); + if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); cli->mem_ctx = NULL; -- cgit From c44a9d25a2bfff9d5ebede80f30e13e41aca797c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jul 2003 23:05:57 +0000 Subject: Added the "required" keyword to the "client signing" parameter to force it on. Fail if missmatch. Small format tidyups in smbd/sesssetup.c. Preparing to add signing on server side. Jeremy. (This used to be commit c390b3e4cd68cfc233ddf14d139e25d40f050f27) --- source3/libsmb/clientgen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 93fa94c1db..58c5ad8cd3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -261,6 +261,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; + + if (lp_client_signing() == Required) + cli->sign_info.mandatory_signing = True; if (!cli->outbuf || !cli->inbuf) goto error; -- cgit From aed434ea9baf430bf7513ca3fb1f7b2f01792341 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 16 Jul 2003 05:51:10 +0000 Subject: Spelling. (This used to be commit 2750418752e491c5e87f0f2adf253291e31ee4c2) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 58c5ad8cd3..cd9edb1cc9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -141,7 +141,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - cli_caclulate_sign_mac(cli); + cli_calculate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; -- cgit From 29ca70cd34d3ba927ea1a9915ebd247f64965bd5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 23:49:29 +0000 Subject: Add a command line option (-S on|off|required) to enable signing on client connections. Overrides smb.conf parameter if set. Jeremy. (This used to be commit 879309671df6b530e0bff69559422a417da4a307) --- source3/libsmb/clientgen.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cd9edb1cc9..cdda2eb224 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -208,6 +208,27 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) cli->user_name, cli->domain)); } +/**************************************************************************** + Set the signing state (used from the command line). +****************************************************************************/ + +void cli_setup_signing_state(struct cli_state *cli, int signing_state) +{ + if (signing_state == Undefined) + return; + + if (signing_state == False) { + cli->sign_info.allow_smb_signing = False; + cli->sign_info.mandatory_signing = False; + return; + } + + cli->sign_info.allow_smb_signing = True; + + if (signing_state == Required) + cli->sign_info.mandatory_signing = True; +} + /**************************************************************************** Initialise a client structure. ****************************************************************************/ -- cgit From 2443f7ffa20a683eabb792182cb0206402ad8059 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 00:29:45 +0000 Subject: Correct fix (removed the earlier band-aid) for what I thought was a signing bug with w2k. Turns out that when we're doing a trans/trans2/nttrans call the MID and send_sequence_number and reply_sequence_number must remain constant. This was something we got very wrong in earlier versions of Samba. I can now get a directory listing from WINNT\SYSTEM32 with the older earlier parameters for clilist.c This still needs to be fixed for the server side of Samba, client appears to be working happily now (I'm doing a signed smbtar download of an entire W2K3 image to test this :-). Jeremy. (This used to be commit 2093a3130d4087d0659b497eebd580e7a66e5aa3) --- source3/libsmb/clientgen.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cdda2eb224..bc5f1462cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -157,6 +157,10 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } + /* Increment the mid so we can tell between responses. */ + cli->mid++; + if (!cli->mid) + cli->mid++; return True; } -- cgit From ea403855075b75150b81e51e96774c95b92f369a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2003 20:26:24 +0000 Subject: Only close anything that is not fid 0. Was very confusing in ethereal... Volker (This used to be commit 9f453f27be7eeb792b57d5c60284bb5efc84b408) --- source3/libsmb/clientgen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bc5f1462cc..308ce31fd0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -339,7 +339,9 @@ void cli_nt_session_close(struct cli_state *cli) ntlmssp_client_end(&cli->ntlmssp_pipe_state); } - cli_close(cli, cli->nt_pipe_fnum); + if (cli->nt_pipe_fnum != 0) + cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; cli->pipe_idx = -1; } -- cgit From 245fbf7efbc42530c81d5aac66681bb892c97557 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Sep 2003 01:12:39 +0000 Subject: Used cachegrind to track down some bottlenecks. Removed calls to clobber_region when not compiling with developer as they were hiding speed problems. Added fast path to convert_string() when dealing with ascii -> ascii, ucs2-le to ascii and ascii to ucs2-le with values <= 0x7F. This gives a speedup of 22% on my nbench tests. Next I will do this on convert_string_allocate. Jeremy. (This used to be commit ef140d15ea0d76a3e7cdcadbfd3e917c210a9411) --- source3/libsmb/clientgen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 308ce31fd0..0a134f715d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -299,9 +299,12 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); + +#if defined(DEVELOPER) /* just because we over-allocate, doesn't mean it's right to use it */ clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); +#endif /* initialise signing */ cli_null_set_signing(cli); -- cgit From f589164ed94d79161d0798296c325b81c5eadbc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 21:19:00 +0000 Subject: Patch from Stefan Metzmacher to fix signing problems when reverse connecting back to a client for printer notify. Jeremy. (This used to be commit 06aa434c3fdb139e3f3143d19413556945cbcd4f) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0a134f715d..9b54acf775 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -59,7 +59,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL ret; for(;;) { - ret = receive_smb(fd, buffer, timeout); + ret = receive_smb_raw(fd, buffer, timeout); if (!ret) { DEBUG(10,("client_receive_smb failed\n")); -- 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/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9b54acf775..0873700fc0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -339,7 +339,7 @@ close the session void cli_nt_session_close(struct cli_state *cli) { if (cli->ntlmssp_pipe_state) { - ntlmssp_client_end(&cli->ntlmssp_pipe_state); + ntlmssp_end(&cli->ntlmssp_pipe_state); } if (cli->nt_pipe_fnum != 0) @@ -375,9 +375,10 @@ void cli_close_connection(struct cli_state *cli) cli_free_signing_context(cli); data_blob_free(&cli->secblob); + data_blob_free(&cli->user_session_key); if (cli->ntlmssp_pipe_state) - ntlmssp_client_end(&cli->ntlmssp_pipe_state); + ntlmssp_end(&cli->ntlmssp_pipe_state); if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); -- cgit From 56ce6136792478c63d371a7b187c1318043e081f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 16:22:47 +0000 Subject: updating release notes & merging Derrel Lipman's libsmbclient patch from HEAD (This used to be commit 5fbfaa687a3674287eeadd205f56b2b253a9e2a9) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0873700fc0..8542eea064 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,6 +367,17 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { + /* + * tell our peer to free his resources. Wihtout this, when an + * application attempts to do a graceful shutdown and calls + * smbc_free_context() to clean up all connections, some connections + * can remain active on the peer end, until some (long) timeout period + * later. This tree disconnect forces the peer to clean up, since the + * connection will be going away. + */ + if ( cli->cnum != (uint16)-1 ) + cli_tdis(cli); + cli_nt_session_close(cli); cli_nt_netlogon_netsec_session_close(cli); -- cgit From e9a7e67e01c115328f95690cbf63ca1ef0b4d408 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:33:59 +0000 Subject: Merge from HEAD the SMB signing patch that I developed a couple of weeks ago. This patch re-adds support for 'optional' SMB signing. It also ensures that we are much more careful about when we enable signing, particularly with on-the-fly smb.conf reloads. The client code will now attempt to use smb signing by default, and disable it if the server doesn't correctly support it. Andrew Bartlett (This used to be commit e27b5cbe75d89ec839dafd52dd33101885a4c263) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8542eea064..66edc3ce38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, True)) { DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); -- cgit From c4255df992d6ec6bb892bf0d39a32a00d4d570ae Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 6 Apr 2004 11:45:02 +0000 Subject: r76: Fix smbfs problem with Tree Disconnect issued before smbfs starts its work. We use cli_state.smb_rw_error to pass this specific case into cli_close_connection() from smbmount as smb_rw_error can have only selected number of states and it is ignored in cli_close_connection(). Compiled and tested by Lars Mueller from SuSE on x86, x86_64, ppc, ppc64, s390 and s390x. (This used to be commit 738666ce0a310fae14476020fd6dac027b0e3ec5) --- source3/libsmb/clientgen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 66edc3ce38..6edc83c9d7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -374,8 +374,12 @@ void cli_close_connection(struct cli_state *cli) * can remain active on the peer end, until some (long) timeout period * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. + * + * Also, do not do tree disconnect when cli->smb_rw_error is DO_NOT_DO_TDIS + * the only user for this so far is smbmount which passes opened connection + * down to kernel's smbfs module. */ - if ( cli->cnum != (uint16)-1 ) + if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) cli_tdis(cli); cli_nt_session_close(cli); -- cgit From 5c2cd8aa38771cba24ce3872b35adefbd9050982 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 2 May 2004 10:42:08 +0000 Subject: r446: Close the open NT pipes before the tdis. Volker (This used to be commit ef80490baf9ce38b505b4b322051ae6e3332d662) --- source3/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6edc83c9d7..b75d6be0a6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,6 +367,9 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { + cli_nt_session_close(cli); + cli_nt_netlogon_netsec_session_close(cli); + /* * tell our peer to free his resources. Wihtout this, when an * application attempts to do a graceful shutdown and calls @@ -382,9 +385,6 @@ void cli_close_connection(struct cli_state *cli) if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) cli_tdis(cli); - cli_nt_session_close(cli); - cli_nt_netlogon_netsec_session_close(cli); - SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); -- cgit From 2acd0848663f28afedff9b11b738e048f5ead2cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jun 2004 18:36:45 +0000 Subject: r1154: Change default setting for case sensitivity to "auto". If set to auto then is the client supports it (current clients supported are Samba and CIFSVFS - detected by the negprot strings "Samba", "POSIX 2" and a bare "NT LM 0.12" string) then the setting of the per packet flag smb_flag FLAG_CASELESS_PATHNAMES is taken into account per packet. This allows the linux CIFS client to use Samba in a case sensitive manner. Additional command in smbclient "case_sensitive", toggles the flag in subsequent packets. Docs to follow. Jeremy. (This used to be commit cf84c0fe1a061acc0313f7db124b8f947cdf623d) --- source3/libsmb/clientgen.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b75d6be0a6..281ee3af84 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -176,7 +176,12 @@ void cli_setup_packet(struct cli_state *cli) SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { uint16 flags2; - SCVAL(cli->outbuf,smb_flg,0x8); + if (cli->case_sensitive) { + SCVAL(cli->outbuf,smb_flg,0x0); + } else { + /* Default setting, case insensitive. */ + SCVAL(cli->outbuf,smb_flg,0x8); + } flags2 = FLAGS2_LONG_PATH_COMPONENTS; if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; @@ -273,6 +278,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; + cli->case_sensitive = False; cli->use_spnego = lp_client_use_spnego(); @@ -440,6 +446,17 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) return ret; } +/**************************************************************************** + Set the case sensitivity flag on the packets. Returns old state. +****************************************************************************/ + +BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) +{ + BOOL ret = cli->case_sensitive; + cli->case_sensitive = case_sensitive; + return ret; +} + /**************************************************************************** Send a keepalive packet to the server ****************************************************************************/ -- cgit From 8f93b500320d7d4341dfea37fd1f82d02b1ce980 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jul 2004 01:20:50 +0000 Subject: r1487: Remove unused parameter for the client-side signing functions. Andrew Bartlett (This used to be commit 6d594d5bb119b6bc3f4c7699752666ac24d04745) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 281ee3af84..974ebf91f5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli, True)) { + if (!cli_check_sign_mac(cli)) { DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); -- 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/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 974ebf91f5..682e0d8b85 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -253,7 +253,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) } if (!cli) { - cli = (struct cli_state *)malloc(sizeof(*cli)); + cli = SMB_MALLOC_P(struct cli_state); if (!cli) return NULL; ZERO_STRUCTP(cli); @@ -275,8 +275,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); - cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); + cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); + cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = False; -- cgit From c85d9e735c8294088203f1656ae07a4b0835292c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Jan 2005 15:35:02 +0000 Subject: r4570: Replace cli->nt_pipe_fnum with an array of NT file numbers, one for each supported pipe. Netlogon is still special, as we open that twice, one to do the auth2, the other one with schannel. The client interface is completely unchanged for those who only use a single pie. cli->pipe_idx is used as the index for everything except the "real" client rpc calls, which have been explicitly converted in my last commit. Next step is to get winbind to just use a single smb connection for multiple pipes. Volker (This used to be commit dc294c52e0216424236057ca6cd35e1ebf51d0da) --- source3/libsmb/clientgen.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 682e0d8b85..39fe91172d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -245,6 +245,7 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; + int i; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -315,7 +316,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) /* initialise signing */ cli_null_set_signing(cli); - cli->nt_pipe_fnum = 0; + for (i=0; int_pipe_fnum[i] = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; @@ -344,14 +347,17 @@ close the session void cli_nt_session_close(struct cli_state *cli) { + int i; + if (cli->ntlmssp_pipe_state) { ntlmssp_end(&cli->ntlmssp_pipe_state); } - if (cli->nt_pipe_fnum != 0) - cli_close(cli, cli->nt_pipe_fnum); - - cli->nt_pipe_fnum = 0; + for (i=0; int_pipe_fnum[i] != 0) + cli_close(cli, cli->nt_pipe_fnum[i]); + cli->nt_pipe_fnum[i] = 0; + } cli->pipe_idx = -1; } -- cgit From 37ea9da1fdf7eac31bb0d7ced407d49e3f5900bc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Feb 2005 03:31:22 +0000 Subject: r5495: * add in some code from Mike Nix for the SMBsplopen and SMBsplclose commands (BUG 2010) * clarify some debug messages in smbspool (also from Mike) my changes: * start adding msdfs client routines * enable smbclient to maintain multiple connections * set the CAP_DFS flag for our internal clienht routines. I actualy have a dfs referral working in do_cd() but that code is too ugly to live so I'm not checking it in just yet. Further work is to merge with vl's changes in trunk to support multiple TIDs per cli_state *. (This used to be commit 0449756309812d854037ba0af631abad678e670e) --- source3/libsmb/clientgen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 39fe91172d..369fba3521 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -185,6 +185,8 @@ void cli_setup_packet(struct cli_state *cli) flags2 = FLAGS2_LONG_PATH_COMPONENTS; if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; + if (cli->capabilities & CAP_DFS) + flags2 |= FLAGS2_DFS_PATHNAMES; if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) @@ -283,7 +285,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->use_spnego = lp_client_use_spnego(); - cli->capabilities = CAP_UNICODE | CAP_STATUS32; + cli->capabilities = CAP_UNICODE | CAP_STATUS32 | CAP_DFS; /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 -- cgit From 82379c7bd1827601630da120f5b5ebb9061ce2b5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Mar 2005 20:14:24 +0000 Subject: r5729: partial fixes for BUG 2308; libsmbclient patches from Derrell Lipman (This used to be commit 88678bc05c3018eb181f97523a0b84b60e3c358d) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 369fba3521..b7bc780a1a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -282,6 +282,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = False; + cli->smb_rw_error = 0; cli->use_spnego = lp_client_use_spnego(); -- 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/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b7bc780a1a..e787650c2f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,6 +22,8 @@ #include "includes.h" +extern int smb_read_error; + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -81,7 +83,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ -- cgit From fed660877c16562265327c6093ea645cf4176b5c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 22:10:34 +0000 Subject: r7415: * big change -- volker's new async winbindd from trunk (This used to be commit a0ac9a8ffd4af31a0ebc423b4acbb2f043d865b8) --- source3/libsmb/clientgen.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e787650c2f..2977099f7d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int smb_read_error; - /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -83,6 +81,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -321,9 +320,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); for (i=0; int_pipe_fnum[i] = 0; + cli->pipes[i].fnum = 0; - cli->saved_netlogon_pipe_fnum = 0; + cli->netlogon_pipe.fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; @@ -353,14 +352,14 @@ void cli_nt_session_close(struct cli_state *cli) { int i; - if (cli->ntlmssp_pipe_state) { - ntlmssp_end(&cli->ntlmssp_pipe_state); - } - for (i=0; int_pipe_fnum[i] != 0) - cli_close(cli, cli->nt_pipe_fnum[i]); - cli->nt_pipe_fnum[i] = 0; + if (cli->pipes[i].pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + ntlmssp_end(&cli->pipes[i].ntlmssp_pipe_state); + } + + if (cli->pipes[i].fnum != 0) + cli_close(cli, cli->pipes[i].fnum); + cli->pipes[i].fnum = 0; } cli->pipe_idx = -1; } @@ -371,9 +370,9 @@ close the NETLOGON session holding the session key for NETSEC void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) { - if (cli->saved_netlogon_pipe_fnum != 0) { - cli_close(cli, cli->saved_netlogon_pipe_fnum); - cli->saved_netlogon_pipe_fnum = 0; + if (cli->netlogon_pipe.fnum != 0) { + cli_close(cli, cli->netlogon_pipe.fnum); + cli->netlogon_pipe.fnum = 0; } } @@ -408,8 +407,8 @@ void cli_close_connection(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->ntlmssp_pipe_state) - ntlmssp_end(&cli->ntlmssp_pipe_state); + if (cli->pipes[cli->pipe_idx].pipe_auth_flags & AUTH_PIPE_NTLMSSP) + ntlmssp_end(&cli->pipes[cli->pipe_idx].ntlmssp_pipe_state); if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); -- cgit From 33a4c0b5a1052026193dcbb800e2bccb1b832730 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jun 2005 22:26:08 +0000 Subject: r7554: Refactor very messy code in util_sock.c Remove write_socket_data/read_socket_data as they do nothing that write_socket/read_socket don't do. Add a more useful error message when read_socket/write_socket error out on the main client fd for a process (ie. try and list the IP of the client that errored). Jeremy. (This used to be commit cbd7578e7c226e6a8002542141b914ed4c7a8269) --- source3/libsmb/clientgen.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2977099f7d..2e21473511 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -127,6 +127,21 @@ BOOL cli_receive_smb(struct cli_state *cli) return True; } +static ssize_t write_socket(int fd, const char *buf, size_t len) +{ + ssize_t ret=0; + + DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); + ret = write_data(fd,buf,len); + + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); + if(ret <= 0) + DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + (int)len, fd, strerror(errno) )); + + return(ret); +} + /**************************************************************************** Send an smb to a fd. ****************************************************************************/ -- cgit From ab398643a4e44211696ef5ce72b62ab7ecee7bc9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 19 Jul 2005 02:37:04 +0000 Subject: r8572: Remove crufty #define NO_SYSLOG as it's not used at all anymore. (This used to be commit 985dbb47d925e79c1195ca219f7ab5d6648b22b8) --- source3/libsmb/clientgen.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2e21473511..f1794ab5dc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /**************************************************************************** -- 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/libsmb/clientgen.c | 83 +++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 42 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f1794ab5dc..bc64cc919b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -221,15 +221,16 @@ void cli_setup_bcc(struct cli_state *cli, void *p) Initialise credentials of a client structure. ****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) +void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password) { - /* copy_nt_creds(&cli->usr, usr); */ - fstrcpy(cli->domain , usr->domain); - fstrcpy(cli->user_name, usr->user_name); - memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); + fstrcpy(cli->domain, domain); + fstrcpy(cli->user_name, username); + pwd_set_cleartext(&cli->pwd, password); + if (!*username) { + cli->pwd.null_pwd = True; + } - DEBUG(10,("cli_init_creds: user %s domain %s\n", - cli->user_name, cli->domain)); + DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); } /**************************************************************************** @@ -260,7 +261,6 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; - int i; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -332,16 +332,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) /* initialise signing */ cli_null_set_signing(cli); - for (i=0; ipipes[i].fnum = 0; - - cli->netlogon_pipe.fnum = 0; - cli->initialised = 1; cli->allocated = alloced_cli; - cli->pipe_idx = -1; - return cli; /* Clean up after malloc() error */ @@ -358,34 +351,42 @@ struct cli_state *cli_initialise(struct cli_state *cli) } /**************************************************************************** -close the session -****************************************************************************/ + External interface. + Close an open named pipe over SMB. Free any authentication data. + ****************************************************************************/ -void cli_nt_session_close(struct cli_state *cli) +void cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - int i; - - for (i=0; ipipes[i].pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - ntlmssp_end(&cli->pipes[i].ntlmssp_pipe_state); - } + if (!cli_close(cli->cli, cli->fnum)) { + DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " + "to machine %s. Error was %s\n", + cli->pipe_name, + cli->cli->desthost, + cli_errstr(cli->cli))); + } - if (cli->pipes[i].fnum != 0) - cli_close(cli, cli->pipes[i].fnum); - cli->pipes[i].fnum = 0; + if (cli->auth.cli_auth_data_free_func) { + (*cli->auth.cli_auth_data_free_func)(&cli->auth); } - cli->pipe_idx = -1; + + DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", + cli->pipe_name, cli->cli->desthost )); + + DLIST_REMOVE(cli->cli->pipe_list, cli); + talloc_destroy(cli->mem_ctx); } /**************************************************************************** -close the NETLOGON session holding the session key for NETSEC + Close all pipes open on this session. ****************************************************************************/ -void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) +void cli_nt_pipes_close(struct cli_state *cli) { - if (cli->netlogon_pipe.fnum != 0) { - cli_close(cli, cli->netlogon_pipe.fnum); - cli->netlogon_pipe.fnum = 0; + struct rpc_pipe_client *cp, *next; + + for (cp = cli->pipe_list; cp; cp = next) { + next = cp->next; + cli_rpc_pipe_close(cp); } } @@ -395,8 +396,7 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { - cli_nt_session_close(cli); - cli_nt_netlogon_netsec_session_close(cli); + cli_nt_pipes_close(cli); /* * tell our peer to free his resources. Wihtout this, when an @@ -410,8 +410,9 @@ void cli_close_connection(struct cli_state *cli) * the only user for this so far is smbmount which passes opened connection * down to kernel's smbfs module. */ - if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) + if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) { cli_tdis(cli); + } SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); @@ -420,19 +421,16 @@ void cli_close_connection(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->pipes[cli->pipe_idx].pipe_auth_flags & AUTH_PIPE_NTLMSSP) - ntlmssp_end(&cli->pipes[cli->pipe_idx].ntlmssp_pipe_state); - if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); cli->mem_ctx = NULL; } - if (cli->fd != -1) + if (cli->fd != -1) { close(cli->fd); + } cli->fd = -1; cli->smb_rw_error = 0; - } /**************************************************************************** @@ -444,8 +442,9 @@ void cli_shutdown(struct cli_state *cli) BOOL allocated = cli->allocated; cli_close_connection(cli); ZERO_STRUCTP(cli); - if (allocated) + if (allocated) { free(cli); + } } /**************************************************************************** -- cgit From 0af6dcacec1831bad1e901383a2c6458e1b0606f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Nov 2005 17:53:21 +0000 Subject: r11976: (Slightly modified) Volker fix for #3293. Use SMBecho instead of chkpath to keep a connection alive. Jeremy. (This used to be commit f1c88de7a28942b6aaa634551dde7a8af91f4de3) --- source3/libsmb/clientgen.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bc64cc919b..6dc7386c03 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -481,6 +481,7 @@ BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) /**************************************************************************** Send a keepalive packet to the server ****************************************************************************/ + BOOL cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { @@ -495,3 +496,36 @@ BOOL cli_send_keepalive(struct cli_state *cli) } return True; } + +/**************************************************************************** + Send/receive a SMBecho command: ping the server +****************************************************************************/ + +BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) +{ + char *p; + + SMB_ASSERT(length < 1024); + + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,1,length,True); + SCVAL(cli->outbuf,smb_com,SMBecho); + SSVAL(cli->outbuf,smb_tid,65535); + SSVAL(cli->outbuf,smb_vwv0,1); + cli_setup_packet(cli); + p = smb_buf(cli->outbuf); + memcpy(p, data, length); + p += length; + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_is_error(cli)) { + return False; + } + return True; +} -- cgit From 765daab643c2957297e71b26de515c05b04d244d Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 14 Dec 2005 04:00:58 +0000 Subject: r12225: r11729@cabra: derrell | 2005-12-13 22:59:45 -0500 1. Fix a crash bug which should have reared its ugly head ages ago, but for some reason, remained dormant until recently. The bug pertained to libsmbclient doing a structure assignment of a cli after having opened a pipe. The pipe open code makes a copy of the cli pointer that was passed to it. If the cli is later copied (and that cli pointer that was saved is no longer valid), the pipe code will cause a crash during shutdown or when the copied cli is closed. 2. The 'type' field in enumerated shares was not being set correctly with the new RPC-based mechanism for enumerating shares. (This used to be commit 62a02b8f2a1fcb66881a9c9636e0b27e3049c5a1) --- source3/libsmb/clientgen.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6dc7386c03..2f980adcf8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -358,11 +358,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) void cli_rpc_pipe_close(struct rpc_pipe_client *cli) { if (!cli_close(cli->cli, cli->fnum)) { - DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " - "to machine %s. Error was %s\n", - cli->pipe_name, - cli->cli->desthost, - cli_errstr(cli->cli))); + DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " + "fnum 0x%x " + "to machine %s. Error was %s\n", + cli->pipe_name, + (int) cli->fnum, + cli->cli->desthost, + cli_errstr(cli->cli))); } if (cli->auth.cli_auth_data_free_func) { -- 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/libsmb/clientgen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2f980adcf8..55addd44a6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -353,11 +353,14 @@ struct cli_state *cli_initialise(struct cli_state *cli) /**************************************************************************** External interface. Close an open named pipe over SMB. Free any authentication data. + Returns False if the cli_close call failed. ****************************************************************************/ -void cli_rpc_pipe_close(struct rpc_pipe_client *cli) +BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - if (!cli_close(cli->cli, cli->fnum)) { + BOOL ret = cli_close(cli->cli, cli->fnum); + + if (!ret) { DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " "fnum 0x%x " "to machine %s. Error was %s\n", @@ -376,6 +379,7 @@ void cli_rpc_pipe_close(struct rpc_pipe_client *cli) DLIST_REMOVE(cli->cli->pipe_list, cli); talloc_destroy(cli->mem_ctx); + return ret; } /**************************************************************************** -- cgit From 0d7f6d650dd3d2c77711d00ffb41e829bb49905f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Feb 2006 04:56:53 +0000 Subject: r13614: First part of the bugfix for #3510 - net join fails against server with schannel disabled. Second part will come tomorrow (fixing net_rpc_join_ok()). Jeremy. (This used to be commit 7de1ee18619bf99c5db45692e085d0646e52378f) --- source3/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 55addd44a6..83664b0b32 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -358,7 +358,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - BOOL ret = cli_close(cli->cli, cli->fnum); + BOOL ret; + + if (!cli) { + return False; + } + + ret = cli_close(cli->cli, cli->fnum); if (!ret) { DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " -- cgit From 19b22b5c903cb08a8f9d2b0647c0ecca211e8cb9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 24 Feb 2006 06:29:15 +0000 Subject: r13671: fix return value in (void)fn() (This used to be commit 249dba0386833803805a742aa6697cc75566f05c) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 83664b0b32..d0525d99b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -361,7 +361,7 @@ BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) BOOL ret; if (!cli) { - return False; + return; } ret = cli_close(cli->cli, cli->fnum); -- cgit From a0ac1d5913ad182abe63d1076b775d1d6dac3365 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 24 Feb 2006 16:06:18 +0000 Subject: r13676: have to return a value from a non-void function (This used to be commit 70e7c9de9dee9317164c0f96a44827ae8b959254) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d0525d99b9..83664b0b32 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -361,7 +361,7 @@ BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) BOOL ret; if (!cli) { - return; + return False; } ret = cli_close(cli->cli, cli->fnum); -- cgit From f40e9fcc5b75fdd272a8de17c560cdc5b3e68694 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Jun 2006 17:23:54 +0000 Subject: r16356: Helping derrell out. Jeremy. Only set the DFS capability flag if the share is a DFS root. Fixes bug 3814. (This used to be commit 6193f1170819096ea8a646e5a456f627df83872d) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 83664b0b32..f5116234c8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -198,7 +198,7 @@ void cli_setup_packet(struct cli_state *cli) flags2 = FLAGS2_LONG_PATH_COMPONENTS; if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; - if (cli->capabilities & CAP_DFS) + if ((cli->capabilities & CAP_DFS) && cli->dfsroot) flags2 |= FLAGS2_DFS_PATHNAMES; if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; -- cgit From 20286e5c036fab3621b81cd72a40c9640a60fc20 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 22 Jun 2006 08:52:01 +0000 Subject: r16458: Increase debuglevel of cli_rpc_pipe_close(). Guenther (This used to be commit 840ac23ec007df445892d851144d6458c4e06a6b) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f5116234c8..8342df0f1d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,7 +367,7 @@ BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) ret = cli_close(cli->cli, cli->fnum); if (!ret) { - DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " + DEBUG(1,("cli_rpc_pipe_close: cli_close failed on pipe %s, " "fnum 0x%x " "to machine %s. Error was %s\n", cli->pipe_name, -- 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/libsmb/clientgen.c | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8342df0f1d..4608d40d46 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -255,12 +255,12 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) } /**************************************************************************** - Initialise a client structure. + Initialise a client structure. Always returns a malloc'ed struct. ****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) +struct cli_state *cli_initialise(void) { - BOOL alloced_cli = False; + struct cli_state *cli = NULL; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -268,17 +268,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) return NULL; } + cli = SMB_MALLOC_P(struct cli_state); if (!cli) { - cli = SMB_MALLOC_P(struct cli_state); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - alloced_cli = True; + return NULL; } - if (cli->initialised) - cli_close_connection(cli); - ZERO_STRUCTP(cli); cli->port = 0; @@ -333,7 +327,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); cli->initialised = 1; - cli->allocated = alloced_cli; return cli; @@ -343,10 +336,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); - - if (alloced_cli) - SAFE_FREE(cli); - + SAFE_FREE(cli); return NULL; } @@ -403,10 +393,10 @@ void cli_nt_pipes_close(struct cli_state *cli) } /**************************************************************************** - Close a client connection and free the memory without destroying cli itself. + Shutdown a client structure. ****************************************************************************/ -void cli_close_connection(struct cli_state *cli) +void cli_shutdown(struct cli_state *cli) { cli_nt_pipes_close(cli); @@ -443,20 +433,8 @@ void cli_close_connection(struct cli_state *cli) } cli->fd = -1; cli->smb_rw_error = 0; -} -/**************************************************************************** - Shutdown a client structure. -****************************************************************************/ - -void cli_shutdown(struct cli_state *cli) -{ - BOOL allocated = cli->allocated; - cli_close_connection(cli); - ZERO_STRUCTP(cli); - if (allocated) { - free(cli); - } + SAFE_FREE(cli); } /**************************************************************************** -- cgit From 40665edf5e6043ad5a8f46731a79ec1d5835b62a Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 00:50:34 +0000 Subject: r18011: Should fix bug 3835. Jeremy: requires your eyes... If the remote connection timed out while cli_list() was retrieving its list of files, the error was not returned to the user, e.g. via smbc_opendir(), so the user didn't have a way to know to set the timeout longer and try again. This problem would occur when a very large directory is being read with a too-small timeout on the cli. Jeremy, although there were a couple of areas that needed to be handled, I needed to make one change that you should bless, in libsmb/clientgen.c. It was setting cli->smb_rw_error = smb_read_error; but smb_read_error is zero, so this had no effect. I'm now doing cli->smb_rw_error = READ_TIMEOUT; instead, and according to the OP, these (cumulative) changes (in a slightly different form) solve the problem. Please confirm this smb_rw_error change will have no other adverse effects that you can see. Derrell (This used to be commit fa664b24b829f973156486896575c1007b6d7b01) --- source3/libsmb/clientgen.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4608d40d46..3a84a5bd4d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,7 +79,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -107,9 +106,9 @@ BOOL cli_receive_smb(struct cli_state *cli) } /* If the server is not responding, note that now */ - if (!ret) { - cli->smb_rw_error = smb_read_error; + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); + cli->smb_rw_error = READ_TIMEOUT; close(cli->fd); cli->fd = -1; return ret; -- cgit From 6fc90da054e06ac4f9db673e237faed6ccc88207 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 02:28:22 +0000 Subject: r18014: revert a possibly unnecessary change (This used to be commit 9c93abf25e391348fe3864fca0079f231b89467c) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3a84a5bd4d..24851961d0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,6 +79,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -108,7 +109,7 @@ BOOL cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (!ret) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = READ_TIMEOUT; + cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; return ret; -- cgit From 791f48f167de339c8ae371e5c80706511fd10018 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 17:38:42 +0000 Subject: r20124: clean up nested extern declaration warnings (This used to be commit ac3eb7813e33b9a2e78c9158433f7ed62c3b62bb) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 24851961d0..68ecb131b1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,6 +20,8 @@ #include "includes.h" +extern int smb_read_error; + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -79,7 +81,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ -- cgit From ecd496f06654e8316260c9a6ddab5e473f9cc452 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Mar 2007 00:32:54 +0000 Subject: r21865: Add in the stubs for SMB transport encryption. Will flesh these out as I implement. Don't add to SAMBA_3_0_25, this is experimental code. NFSv4 you're now officially on notice... :-). Jeremy. (This used to be commit 5bfe638f2172e272741997100ee5ae8ff280494d) --- source3/libsmb/clientgen.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 68ecb131b1..cdf36d9b9c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -54,9 +54,13 @@ int cli_set_port(struct cli_state *cli, int port) should never go into a blocking read. ****************************************************************************/ -static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +static BOOL client_receive_smb(struct cli_state *cli) { BOOL ret; + NTSTATUS status; + int fd = cli->fd; + char *buffer = cli->inbuf; + unsigned int timeout = cli->timeout; for(;;) { ret = receive_smb_raw(fd, buffer, timeout); @@ -71,6 +75,15 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) if(CVAL(buffer,0) != SMBkeepalive) break; } + status = cli_decrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status))); + cli->smb_rw_error = READ_BAD_DECRYPT; + close(cli->fd); + cli->fd = -1; + return False; + } show_msg(buffer); return ret; } @@ -88,7 +101,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return False; again: - ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + ret = client_receive_smb(cli); if (ret) { /* it might be an oplock break request */ @@ -132,7 +145,7 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_data(fd,buf,len); - + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); if(ret <= 0) DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", @@ -147,16 +160,28 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) BOOL cli_send_smb(struct cli_state *cli) { + NTSTATUS status; size_t len; size_t nwritten=0; ssize_t ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) + if (cli->fd == -1) { return False; + } cli_calculate_sign_mac(cli); + status = cli_encrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return False; + } + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { @@ -173,8 +198,9 @@ BOOL cli_send_smb(struct cli_state *cli) } /* Increment the mid so we can tell between responses. */ cli->mid++; - if (!cli->mid) + if (!cli->mid) { cli->mid++; + } return True; } -- cgit From 7ccf45684a1f83d7d48a4227aa56c53081d68283 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 22:45:35 +0000 Subject: r21880: Make client and server calls into encryption code symetrical, depending on encryption context pointer. Jeremy. (This used to be commit d3f3ced6c8a03d971143baf878158d671dfcbc3b) --- source3/libsmb/clientgen.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cdf36d9b9c..52ffdc24e7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -164,6 +164,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { @@ -172,7 +173,7 @@ BOOL cli_send_smb(struct cli_state *cli) cli_calculate_sign_mac(cli); - status = cli_encrypt_message(cli); + status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; @@ -182,11 +183,12 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } - len = smb_len(cli->outbuf) + 4; + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { + cli_free_enc_buffer(cli, buf_out); close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; @@ -196,6 +198,9 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } + + cli_free_enc_buffer(cli, buf_out); + /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) { @@ -447,6 +452,8 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); + cli_free_encryption_context(cli); + data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); -- cgit From 8c395be5e514a28f13608a462c0c0e8417e21160 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 23:49:57 +0000 Subject: r21922: Fixed the build by rather horrid means. I really need to restructure libsmb/smb_signing.c so it isn't in the base libs path but lives in libsmb instead (like smb_seal.c does). Jeremy. (This used to be commit 1b828f051d0782201f697de15ff973bd6b097d5b) --- source3/libsmb/clientgen.c | 58 +++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 27 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 52ffdc24e7..1aa0ddcc10 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -57,7 +57,6 @@ int cli_set_port(struct cli_state *cli, int port) static BOOL client_receive_smb(struct cli_state *cli) { BOOL ret; - NTSTATUS status; int fd = cli->fd; char *buffer = cli->inbuf; unsigned int timeout = cli->timeout; @@ -75,14 +74,16 @@ static BOOL client_receive_smb(struct cli_state *cli) if(CVAL(buffer,0) != SMBkeepalive) break; } - status = cli_decrypt_message(cli); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status))); - cli->smb_rw_error = READ_BAD_DECRYPT; - close(cli->fd); - cli->fd = -1; - return False; + if (cli_encryption_on(cli)) { + NTSTATUS status = cli_decrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status))); + cli->smb_rw_error = READ_BAD_DECRYPT; + close(cli->fd); + cli->fd = -1; + return False; + } } show_msg(buffer); return ret; @@ -129,13 +130,15 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = READ_BAD_SIG; - close(cli->fd); - cli->fd = -1; - return False; - }; + if (!cli_encryption_on(cli)) { + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; + return False; + } + } return True; } @@ -160,7 +163,6 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) BOOL cli_send_smb(struct cli_state *cli) { - NTSTATUS status; size_t len; size_t nwritten=0; ssize_t ret; @@ -171,16 +173,18 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } - cli_calculate_sign_mac(cli); - - status = cli_encrypt_message(cli, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; - DEBUG(0,("Error in encrypting client message. Error %s\n", - nt_errstr(status) )); - return False; + if (cli_encryption_on(cli)) { + NTSTATUS status = cli_encrypt_message(cli, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return False; + } + } else { + cli_calculate_sign_mac(cli); } len = smb_len(buf_out) + 4; -- cgit From d506caf2b586e8fe06d38d17658f12400e3cccc5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Mar 2007 19:41:17 +0000 Subject: r21939: Fix missing initialization that broke the build farm. Thanks to Metze for the heads up. Jeremy. (This used to be commit bb3623be3f2b0686b2b2e671e3e7bd9978f6ed9b) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1aa0ddcc10..a3873a47fe 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -166,7 +166,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out; + char *buf_out = cli->outbuf; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { -- cgit From 34dac35e48ca0c03d2744d9925566665285eb973 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 18:04:36 +0000 Subject: r21990: Stop messing with the signing engine just because we're encrypted. This will make further changes and spec much more clear. Jeremy. (This used to be commit ffa3a5c508a494d22e8ee3ada424a6517ddf8923) --- source3/libsmb/clientgen.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a3873a47fe..92fc72fd5c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -74,6 +74,7 @@ static BOOL client_receive_smb(struct cli_state *cli) if(CVAL(buffer,0) != SMBkeepalive) break; } + if (cli_encryption_on(cli)) { NTSTATUS status = cli_decrypt_message(cli); if (!NT_STATUS_IS_OK(status)) { @@ -130,15 +131,14 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_encryption_on(cli)) { - if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = READ_BAD_SIG; - close(cli->fd); - cli->fd = -1; - return False; - } + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; + return False; } + return True; } @@ -173,6 +173,8 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } + cli_calculate_sign_mac(cli); + if (cli_encryption_on(cli)) { NTSTATUS status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { @@ -183,8 +185,6 @@ BOOL cli_send_smb(struct cli_state *cli) nt_errstr(status) )); return False; } - } else { - cli_calculate_sign_mac(cli); } len = smb_len(buf_out) + 4; -- cgit From 4a66d0e232271968ba96da50274428916a393975 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 21:13:31 +0000 Subject: r21991: I hate Steve French :-). Add support for encryption contexts.... Jeremy. (This used to be commit ae8f3649f773b8a8dcb55921536d038d3475322e) --- source3/libsmb/clientgen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 92fc72fd5c..fc88f7f1e2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -167,6 +167,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t nwritten=0; ssize_t ret; char *buf_out = cli->outbuf; + BOOL enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { @@ -175,7 +176,7 @@ BOOL cli_send_smb(struct cli_state *cli) cli_calculate_sign_mac(cli); - if (cli_encryption_on(cli)) { + if (enc_on) { NTSTATUS status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); @@ -192,7 +193,9 @@ BOOL cli_send_smb(struct cli_state *cli) while (nwritten < len) { ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { - cli_free_enc_buffer(cli, buf_out); + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; -- cgit From 0eab4311946c312795ec5c03c25a340ef0bfc624 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 21:55:43 +0000 Subject: r21992: Fix keepalive processing when encryption turned on. Jeremy. (This used to be commit 8f113ad1918dcd2746ec527ceb79a2a7baa1d415) --- source3/libsmb/clientgen.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc88f7f1e2..b3c38f39ae 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -48,13 +48,13 @@ int cli_set_port(struct cli_state *cli, int port) *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds - This is exactly the same as receive_smb except that it never returns + This is exactly the same as receive_smb except that it can be set to never return a session keepalive packet (just as receive_smb used to do). receive_smb was changed to return keepalives as the oplock processing means this call should never go into a blocking read. ****************************************************************************/ -static BOOL client_receive_smb(struct cli_state *cli) +static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) { BOOL ret; int fd = cli->fd; @@ -71,8 +71,10 @@ static BOOL client_receive_smb(struct cli_state *cli) } /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; + if (eat_keepalives && (CVAL(buffer,0) == SMBkeepalive)) { + continue; + } + break; } if (cli_encryption_on(cli)) { @@ -94,7 +96,7 @@ static BOOL client_receive_smb(struct cli_state *cli) Recv an smb. ****************************************************************************/ -BOOL cli_receive_smb(struct cli_state *cli) +BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) { BOOL ret; @@ -103,7 +105,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return False; again: - ret = client_receive_smb(cli); + ret = client_receive_smb(cli, eat_keepalives); if (ret) { /* it might be an oplock break request */ @@ -142,6 +144,24 @@ BOOL cli_receive_smb(struct cli_state *cli) return True; } +/**************************************************************************** + Recv an smb - eat keepalives. +****************************************************************************/ + +BOOL cli_receive_smb(struct cli_state *cli) +{ + return cli_receive_smb_internal(cli, True); +} + +/**************************************************************************** + Recv an smb - return keepalives. +****************************************************************************/ + +BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) +{ + return cli_receive_smb_internal(cli, False); +} + static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; -- cgit From 208367f4d1869843d024a06313a965455b9ee3be Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 22:27:06 +0000 Subject: r21993: Don't let keepalives interferece with sign or seal in the client code. Jeremy. (This used to be commit 3e901389feedadd64c6ba712ab09cdfb497a9e0a) --- source3/libsmb/clientgen.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b3c38f39ae..95d7cdadd7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -106,6 +106,11 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) again: ret = client_receive_smb(cli, eat_keepalives); + + if (!eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { + /* Give back the keepalive. */ + return True; + } if (ret) { /* it might be an oplock break request */ -- cgit From 3215c09a8147e7df111e4e0817091285cd7240cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 22:37:42 +0000 Subject: r21994: Ignore keepalives in the correct buffer (out not in :-). Jeremy. (This used to be commit 9785528ddf26c4943e8bdfcf7694314a52218520) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 95d7cdadd7..e4712d2f65 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -107,7 +107,7 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) again: ret = client_receive_smb(cli, eat_keepalives); - if (!eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { + if (ret && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { /* Give back the keepalive. */ return True; } -- cgit From 282018a366dec480597c08df310a7826c079b692 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 14 Apr 2007 00:53:38 +0000 Subject: r22212: Cope with signature errors on sessionsetupX logins where the server just reflects our signature back to us. Allow the upper layer to see the real error. Jeremy. (This used to be commit 6cf0b93b1d8cb97dc665e14ace94a259def67724) --- source3/libsmb/clientgen.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e4712d2f65..de575e83a2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -139,6 +139,26 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) } if (!cli_check_sign_mac(cli)) { + /* + * If we get a signature failure in sessionsetup, then + * the server sometimes just reflects the sent signature + * back to us. Detect this and allow the upper layer to + * retrieve the correct Windows error message. + */ + if (CVAL(cli->outbuf,smb_com) == SMBsesssetupX && + (smb_len(cli->inbuf) > (smb_ss_field + 8 - 4)) && + (SVAL(cli->inbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) && + memcmp(&cli->outbuf[smb_ss_field],&cli->inbuf[smb_ss_field],8) == 0 && + cli_is_error(cli)) { + + /* + * Reflected signature on login error. + * Set bad sig but don't close fd. + */ + cli->smb_rw_error = READ_BAD_SIG; + return True; + } + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index de575e83a2..e1dacb3921 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -298,7 +298,7 @@ void cli_setup_packet(struct cli_state *cli) void cli_setup_bcc(struct cli_state *cli, void *p) { - set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); + set_message_bcc(NULL,cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } /**************************************************************************** @@ -584,7 +584,7 @@ BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,length,True); + set_message(NULL,cli->outbuf,1,length,True); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,1); -- cgit From 32106b23951e01fb17f814584ebbcc8d7288cb75 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 00:07:38 +0000 Subject: r22920: Add in the UNIX capability for 24-bit readX, as discussed with the Apple guys and Linux kernel guys. Still looking at how to do writeX as there's no recvfile(). Jeremy. (This used to be commit a53268fb2082de586e2df250d8ddfcff53379102) --- source3/libsmb/clientgen.c | 127 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 14 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e1dacb3921..1a4b1f770f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. SMB client generic functions Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jeremy Allison 2007. 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 @@ -54,20 +55,20 @@ int cli_set_port(struct cli_state *cli, int port) should never go into a blocking read. ****************************************************************************/ -static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) +static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, size_t maxlen) { - BOOL ret; + ssize_t len; int fd = cli->fd; char *buffer = cli->inbuf; unsigned int timeout = cli->timeout; for(;;) { - ret = receive_smb_raw(fd, buffer, timeout); + len = receive_smb_raw(fd, buffer, timeout, maxlen); - if (!ret) { + if (len < 0) { DEBUG(10,("client_receive_smb failed\n")); show_msg(buffer); - return ret; + return len; } /* Ignore session keepalive packets. */ @@ -85,11 +86,11 @@ static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) cli->smb_rw_error = READ_BAD_DECRYPT; close(cli->fd); cli->fd = -1; - return False; + return -1; } } show_msg(buffer); - return ret; + return len; } /**************************************************************************** @@ -98,21 +99,21 @@ static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) { - BOOL ret; + ssize_t len; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) return False; again: - ret = client_receive_smb(cli, eat_keepalives); + len = client_receive_smb(cli, eat_keepalives, 0); - if (ret && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { + if (len >= 0 && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { /* Give back the keepalive. */ return True; } - if (ret) { + if (len > 0) { /* it might be an oplock break request */ if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && CVAL(cli->inbuf,smb_com) == SMBlockingX && @@ -121,7 +122,9 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) if (cli->oplock_handler) { int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return False; + if (!cli->oplock_handler(cli, fnum, level)) { + return False; + } } /* try to prevent loops */ SCVAL(cli->inbuf,smb_com,0xFF); @@ -130,12 +133,12 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) } /* If the server is not responding, note that now */ - if (!ret) { + if (len <= 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; - return ret; + return False; } if (!cli_check_sign_mac(cli)) { @@ -187,6 +190,102 @@ BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) return cli_receive_smb_internal(cli, False); } +/**************************************************************************** + Read the data portion of a readX smb. + The timeout is in milliseconds +****************************************************************************/ + +ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) +{ + if (cli->timeout > 0) { + return read_socket_with_timeout(cli->fd, buffer, len, len, cli->timeout); + } else { + return read_data(cli->fd, buffer, len); + } +} + +/**************************************************************************** + Read a smb readX header. + We can only use this if encryption and signing are off. +****************************************************************************/ + +BOOL cli_receive_smb_readX_header(struct cli_state *cli) +{ + ssize_t len, offset; + + if (cli->fd == -1) + return False; + + again: + + /* Read up to the size of a readX header reply. */ + len = client_receive_smb(cli, True, (smb_size - 4) + 24); + + if (len > 0) { + /* it might be an oplock break request */ + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && + CVAL(cli->inbuf,smb_com) == SMBlockingX && + SVAL(cli->inbuf,smb_vwv6) == 0 && + SVAL(cli->inbuf,smb_vwv7) == 0) { + ssize_t total_len = smb_len(cli->inbuf); + + if (total_len > CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN) { + goto read_err; + } + + /* Read the rest of the data. */ + if (!cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { + goto read_err; + } + + if (cli->oplock_handler) { + int fnum = SVAL(cli->inbuf,smb_vwv2); + unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); + if (!cli->oplock_handler(cli, fnum, level)) return False; + } + /* try to prevent loops */ + SCVAL(cli->inbuf,smb_com,0xFF); + goto again; + } + } + + /* Check it's a non-chained readX reply. */ + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || + (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || + (CVAL(cli->inbuf,smb_com) != SMBreadX)) { + /* + * We're not coping here with asnyc replies to + * other calls. Punt here - we need async client + * libs for this. + */ + goto read_err; + } + + /* + * We know it's a readX reply - ensure we've read the + * padding bytes also. + */ + + offset = SVAL(cli->inbuf,smb_vwv6); + if (offset > len) { + ssize_t ret; + size_t padbytes = offset - len; + ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); + if (ret != padbytes) { + goto read_err; + } + } + + return True; + + read_err: + + cli->smb_rw_error = smb_read_error = READ_ERROR; + close(cli->fd); + cli->fd = -1; + return False; +} + static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; -- cgit From bfb863c57cd1b8fc16cf7cda3cc3989104b4246c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 01:34:22 +0000 Subject: r22924: Fix the build by correctly processing readX errors in the direct read case. Jeremy. (This used to be commit 6fe2ee3bd79fadfe43a9a84e03c398bd339259c1) --- source3/libsmb/clientgen.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1a4b1f770f..9021d1a362 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -249,30 +249,34 @@ BOOL cli_receive_smb_readX_header(struct cli_state *cli) } } - /* Check it's a non-chained readX reply. */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || - (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || - (CVAL(cli->inbuf,smb_com) != SMBreadX)) { + /* If it's not the above size it probably was an error packet. */ + + if ((len == (smb_size - 4) + 24) && !cli_is_error(cli)) { + /* Check it's a non-chained readX reply. */ + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || + (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || + (CVAL(cli->inbuf,smb_com) != SMBreadX)) { + /* + * We're not coping here with asnyc replies to + * other calls. Punt here - we need async client + * libs for this. + */ + goto read_err; + } + /* - * We're not coping here with asnyc replies to - * other calls. Punt here - we need async client - * libs for this. + * We know it's a readX reply - ensure we've read the + * padding bytes also. */ - goto read_err; - } - /* - * We know it's a readX reply - ensure we've read the - * padding bytes also. - */ - - offset = SVAL(cli->inbuf,smb_vwv6); - if (offset > len) { - ssize_t ret; - size_t padbytes = offset - len; - ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); - if (ret != padbytes) { - goto read_err; + offset = SVAL(cli->inbuf,smb_vwv6); + if (offset > len) { + ssize_t ret; + size_t padbytes = offset - len; + ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); + if (ret != padbytes) { + goto read_err; + } } } -- cgit From cc5c058e5992ae8209caaf8ff63d03eff686ce50 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 May 2007 09:53:41 +0000 Subject: r22929: Attempt to fix some build farm failures: On port 139 the first successful packet gives len==0 from the server, so the = in if (len <= 0) { in line 136 of clientgen.c throws a failure. Jeremy, please fix this properly, I'm not merging this to 3_0_26 so that you can filter it when you merge. Volker (This used to be commit 9c5111d8c5064a43762d7d0146acff5e7691dafd) --- source3/libsmb/clientgen.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9021d1a362..92a9678de5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -190,6 +190,32 @@ BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) return cli_receive_smb_internal(cli, False); } +/**************************************************************************** + Recv an smb session reply +****************************************************************************/ + +BOOL cli_receive_sessionreply(struct cli_state *cli) +{ + ssize_t len; + + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) + return False; + + len = client_receive_smb(cli, False, 0); + + /* If the server is not responding, note that now */ + if (len < 0) { + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); + cli->smb_rw_error = smb_read_error; + close(cli->fd); + cli->fd = -1; + return False; + } + + return True; +} + /**************************************************************************** Read the data portion of a readX smb. The timeout is in milliseconds -- cgit From e24acb681b0f0d3a04c1ae50e6c68369e5edc115 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 May 2007 10:59:04 +0000 Subject: r22930: Next attempt to get the build farm in line. Jeremy, please check this and merge if appropriate. (This used to be commit 0bdf4f1a5937abd0ef266700115d74396bc1629c) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 92a9678de5..ef74de9f4b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -260,7 +260,8 @@ BOOL cli_receive_smb_readX_header(struct cli_state *cli) } /* Read the rest of the data. */ - if (!cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { + if ((total_len - len > 0) && + !cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { goto read_err; } -- cgit From 478ccc150ba3b8c87ac67769c46be20a73d14096 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 17:17:25 +0000 Subject: r22950: Fix the issue Volker reported here : "Attempt to fix some build farm failures: On port 139 the first successful packet gives len==0 from the server, so the = in if (len <= 0) { in line 136 of clientgen.c throws a failure." The irritating thing is that I already had it correct in SAMBA_3_0_26 and forgot to merge the change across. len == 0 is a valid return - I messed that up when converting client_receive_smb() to return a length rather than a BOOL. Doh ! Jeremy. (This used to be commit a398bdf08d9efac51af28aed29f2c0f151cd5aad) --- source3/libsmb/clientgen.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ef74de9f4b..43211a6c5a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -133,7 +133,7 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) } /* If the server is not responding, note that now */ - if (len <= 0) { + if (len < 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); cli->smb_rw_error = smb_read_error; close(cli->fd); @@ -190,32 +190,6 @@ BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) return cli_receive_smb_internal(cli, False); } -/**************************************************************************** - Recv an smb session reply -****************************************************************************/ - -BOOL cli_receive_sessionreply(struct cli_state *cli) -{ - ssize_t len; - - /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) - return False; - - len = client_receive_smb(cli, False, 0); - - /* If the server is not responding, note that now */ - if (len < 0) { - DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = smb_read_error; - close(cli->fd); - cli->fd = -1; - return False; - } - - return True; -} - /**************************************************************************** Read the data portion of a readX smb. The timeout is in milliseconds -- 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/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 43211a6c5a..282ebb7cb9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -6,7 +6,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 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/clientgen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 282ebb7cb9..29d4d9c334 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -15,8 +15,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 . */ #include "includes.h" -- cgit From c847b2afe7f4c979499c20869563439e25f0cb7e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 4 Aug 2007 20:08:35 +0000 Subject: r24223: Convert reply_echo to the new API (This used to be commit 4863ff2899419e791ed0e340821072d004fb1d17) --- source3/libsmb/clientgen.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 29d4d9c334..a23e0184d7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -680,9 +680,11 @@ BOOL cli_send_keepalive(struct cli_state *cli) Send/receive a SMBecho command: ping the server ****************************************************************************/ -BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) +BOOL cli_echo(struct cli_state *cli, uint16 num_echos, + unsigned char *data, size_t length) { char *p; + int i; SMB_ASSERT(length < 1024); @@ -690,7 +692,7 @@ BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) set_message(NULL,cli->outbuf,1,length,True); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); - SSVAL(cli->outbuf,smb_vwv0,1); + SSVAL(cli->outbuf,smb_vwv0,num_echos); cli_setup_packet(cli); p = smb_buf(cli->outbuf); memcpy(p, data, length); @@ -699,12 +701,16 @@ BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - if (cli_is_error(cli)) { - return False; + for (i=0; i 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/libsmb/clientgen.c | 96 ++++++++-------------------------------------- 1 file changed, 15 insertions(+), 81 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a23e0184d7..1e3af9a3d7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -48,18 +48,15 @@ int cli_set_port(struct cli_state *cli, int port) *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds - This is exactly the same as receive_smb except that it can be set to never return + This is exactly the same as receive_smb except that it never returns a session keepalive packet (just as receive_smb used to do). receive_smb was changed to return keepalives as the oplock processing means this call should never go into a blocking read. ****************************************************************************/ -static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, size_t maxlen) +static ssize_t client_receive_smb(int fd,char *buffer, unsigned int timeout, size_t maxlen) { ssize_t len; - int fd = cli->fd; - char *buffer = cli->inbuf; - unsigned int timeout = cli->timeout; for(;;) { len = receive_smb_raw(fd, buffer, timeout, maxlen); @@ -71,22 +68,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, si } /* Ignore session keepalive packets. */ - if (eat_keepalives && (CVAL(buffer,0) == SMBkeepalive)) { - continue; - } - break; - } - - if (cli_encryption_on(cli)) { - NTSTATUS status = cli_decrypt_message(cli); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status))); - cli->smb_rw_error = READ_BAD_DECRYPT; - close(cli->fd); - cli->fd = -1; - return -1; - } + if(CVAL(buffer,0) != SMBkeepalive) + break; } show_msg(buffer); return len; @@ -96,7 +79,7 @@ static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, si Recv an smb. ****************************************************************************/ -BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) +BOOL cli_receive_smb(struct cli_state *cli) { ssize_t len; @@ -105,12 +88,7 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) return False; again: - len = client_receive_smb(cli, eat_keepalives, 0); - - if (len >= 0 && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { - /* Give back the keepalive. */ - return True; - } + len = client_receive_smb(cli->fd,cli->inbuf,cli->timeout, 0); if (len > 0) { /* it might be an oplock break request */ @@ -166,29 +144,10 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) close(cli->fd); cli->fd = -1; return False; - } - + }; return True; } -/**************************************************************************** - Recv an smb - eat keepalives. -****************************************************************************/ - -BOOL cli_receive_smb(struct cli_state *cli) -{ - return cli_receive_smb_internal(cli, True); -} - -/**************************************************************************** - Recv an smb - return keepalives. -****************************************************************************/ - -BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) -{ - return cli_receive_smb_internal(cli, False); -} - /**************************************************************************** Read the data portion of a readX smb. The timeout is in milliseconds @@ -205,7 +164,6 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) /**************************************************************************** Read a smb readX header. - We can only use this if encryption and signing are off. ****************************************************************************/ BOOL cli_receive_smb_readX_header(struct cli_state *cli) @@ -218,7 +176,7 @@ BOOL cli_receive_smb_readX_header(struct cli_state *cli) again: /* Read up to the size of a readX header reply. */ - len = client_receive_smb(cli, True, (smb_size - 4) + 24); + len = client_receive_smb(cli->fd, cli->inbuf, cli->timeout, (smb_size - 4) + 24); if (len > 0) { /* it might be an oplock break request */ @@ -296,7 +254,7 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_data(fd,buf,len); - + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); if(ret <= 0) DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", @@ -314,36 +272,18 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out = cli->outbuf; - BOOL enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) { + if (cli->fd == -1) return False; - } cli_calculate_sign_mac(cli); - if (enc_on) { - NTSTATUS status = cli_encrypt_message(cli, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; - DEBUG(0,("Error in encrypting client message. Error %s\n", - nt_errstr(status) )); - return False; - } - } - - len = smb_len(buf_out) + 4; + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); + ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { - if (enc_on) { - cli_free_enc_buffer(cli, buf_out); - } close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; @@ -353,14 +293,10 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } - - cli_free_enc_buffer(cli, buf_out); - /* Increment the mid so we can tell between responses. */ cli->mid++; - if (!cli->mid) { + if (!cli->mid) cli->mid++; - } return True; } @@ -401,7 +337,7 @@ void cli_setup_packet(struct cli_state *cli) void cli_setup_bcc(struct cli_state *cli, void *p) { - set_message_bcc(NULL,cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); + set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } /**************************************************************************** @@ -607,8 +543,6 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); - cli_free_encryption_context(cli); - data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); @@ -689,7 +623,7 @@ BOOL cli_echo(struct cli_state *cli, uint16 num_echos, SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1,length,True); + set_message(cli->outbuf,1,length,True); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,num_echos); -- 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/libsmb/clientgen.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1e3af9a3d7..ca05b2e38a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,7 +79,7 @@ static ssize_t client_receive_smb(int fd,char *buffer, unsigned int timeout, siz Recv an smb. ****************************************************************************/ -BOOL cli_receive_smb(struct cli_state *cli) +bool cli_receive_smb(struct cli_state *cli) { ssize_t len; @@ -166,7 +166,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) Read a smb readX header. ****************************************************************************/ -BOOL cli_receive_smb_readX_header(struct cli_state *cli) +bool cli_receive_smb_readX_header(struct cli_state *cli) { ssize_t len, offset; @@ -267,7 +267,7 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) Send an smb to a fd. ****************************************************************************/ -BOOL cli_send_smb(struct cli_state *cli) +bool cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; @@ -469,9 +469,9 @@ struct cli_state *cli_initialise(void) Returns False if the cli_close call failed. ****************************************************************************/ -BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) +bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - BOOL ret; + bool ret; if (!cli) { return False; @@ -584,9 +584,9 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) Set the case sensitivity flag on the packets. Returns old state. ****************************************************************************/ -BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) +bool cli_set_case_sensitive(struct cli_state *cli, bool case_sensitive) { - BOOL ret = cli->case_sensitive; + bool ret = cli->case_sensitive; cli->case_sensitive = case_sensitive; return ret; } @@ -595,7 +595,7 @@ BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) Send a keepalive packet to the server ****************************************************************************/ -BOOL cli_send_keepalive(struct cli_state *cli) +bool cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { DEBUG(3, ("cli_send_keepalive: fd == -1\n")); @@ -614,7 +614,7 @@ BOOL cli_send_keepalive(struct cli_state *cli) Send/receive a SMBecho command: ping the server ****************************************************************************/ -BOOL cli_echo(struct cli_state *cli, uint16 num_echos, +bool cli_echo(struct cli_state *cli, uint16 num_echos, unsigned char *data, size_t length) { char *p; -- cgit From 329365684bca99bf9020b6638a1357df65c1d938 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 12:21:34 -0700 Subject: Change the client library to write directly out of the incoming buffer in the non-signed case. Speeds up writes by over 10% or so. Complete the server recvfile implementation. Jeremy. (This used to be commit 81ca5853b2475f123faab3b550f0a7b24ae3c208) --- source3/libsmb/clientgen.c | 65 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ca05b2e38a..19210dd069 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -251,15 +251,15 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; - + DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_data(fd,buf,len); - + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); if(ret <= 0) DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", (int)len, fd, strerror(errno) )); - + return(ret); } @@ -300,6 +300,65 @@ bool cli_send_smb(struct cli_state *cli) return True; } +/**************************************************************************** + Send a "direct" writeX smb to a fd. +****************************************************************************/ + +bool cli_send_smb_direct_writeX(struct cli_state *cli, + const char *p, + size_t extradata) +{ + /* First length to send is the offset to the data. */ + size_t len = SVAL(cli->outbuf,smb_vwv11) + 4; + size_t nwritten=0; + ssize_t ret; + + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) { + return false; + } + + if (client_is_signing_on(cli)) { + DEBUG(0,("cli_send_smb_large: cannot send signed packet.\n")); + return false; + } + + while (nwritten < len) { + ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + if (ret <= 0) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", + (int)len,(int)ret, strerror(errno) )); + return false; + } + nwritten += ret; + } + + /* Now write the extra data. */ + nwritten=0; + while (nwritten < extradata) { + ret = write_socket(cli->fd,p+nwritten,extradata - nwritten); + if (ret <= 0) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error writing %d extradata " + "bytes to client. %d (%s)\n", + (int)extradata,(int)ret, strerror(errno) )); + return False; + } + nwritten += ret; + } + + /* Increment the mid so we can tell between responses. */ + cli->mid++; + if (!cli->mid) + cli->mid++; + return true; +} + /**************************************************************************** Setup basics in a outgoing packet. ****************************************************************************/ -- cgit From 73d407968002587eadd0ff13eb413ddf07c78771 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 15:12:42 -0700 Subject: Remove the smb_read_error global variable and replace it with accessor functions. "One global or pstring a day...." :-). Jeremy. (This used to be commit d50d14c300abc83b7015718ec48acc8b3227a273) --- source3/libsmb/clientgen.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 19210dd069..0a8ff4e552 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,8 +20,6 @@ #include "includes.h" -extern int smb_read_error; - /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -112,7 +110,7 @@ bool cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (len < 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = smb_read_error; + cli->smb_rw_error = get_smb_read_error(); close(cli->fd); cli->fd = -1; return False; @@ -135,12 +133,12 @@ bool cli_receive_smb(struct cli_state *cli) * Reflected signature on login error. * Set bad sig but don't close fd. */ - cli->smb_rw_error = READ_BAD_SIG; + cli->smb_rw_error = SMB_READ_BAD_SIG; return True; } DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = READ_BAD_SIG; + cli->smb_rw_error = SMB_READ_BAD_SIG; close(cli->fd); cli->fd = -1; return False; @@ -242,7 +240,8 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) read_err: - cli->smb_rw_error = smb_read_error = READ_ERROR; + set_smb_read_error(SMB_READ_ERROR); + cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; return False; @@ -286,7 +285,7 @@ bool cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; + cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return False; @@ -328,7 +327,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, if (ret <= 0) { close(cli->fd); cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; + cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return false; @@ -343,7 +342,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, if (ret <= 0) { close(cli->fd); cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; + cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d extradata " "bytes to client. %d (%s)\n", (int)extradata,(int)ret, strerror(errno) )); @@ -590,11 +589,11 @@ void cli_shutdown(struct cli_state *cli) * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. * - * Also, do not do tree disconnect when cli->smb_rw_error is DO_NOT_DO_TDIS + * Also, do not do tree disconnect when cli->smb_rw_error is SMB_DO_NOT_DO_TDIS * the only user for this so far is smbmount which passes opened connection * down to kernel's smbfs module. */ - if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) { + if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != SMB_DO_NOT_DO_TDIS ) ) { cli_tdis(cli); } -- cgit From 36441da4240f3e3a296eed65f0796b25b7b05a3a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Nov 2007 11:12:56 -0800 Subject: Remove the horror that was the global smb_rw_error. Each cli struct has it's own local copy of this variable, so use that in client code. In the smbd server, add one static to smbd/proccess.c and use that inside smbd. Fix a bunch of places where smb_rw_error could be set by calling read_data() in places where we weren't reading from the SMB client socket (ie. winbindd). Jeremy. (This used to be commit 255c2adf7b6ef30932b5bb9f142ccef4a5d3d0db) --- source3/libsmb/clientgen.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0a8ff4e552..ee1a0fe3db 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -52,24 +52,26 @@ int cli_set_port(struct cli_state *cli, int port) should never go into a blocking read. ****************************************************************************/ -static ssize_t client_receive_smb(int fd,char *buffer, unsigned int timeout, size_t maxlen) +static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) { ssize_t len; for(;;) { - len = receive_smb_raw(fd, buffer, timeout, maxlen); + len = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, + maxlen, &cli->smb_rw_error); if (len < 0) { DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); + show_msg(cli->inbuf); return len; } /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) + if(CVAL(cli->inbuf,0) != SMBkeepalive) { break; + } } - show_msg(buffer); + show_msg(cli->inbuf); return len; } @@ -86,7 +88,7 @@ bool cli_receive_smb(struct cli_state *cli) return False; again: - len = client_receive_smb(cli->fd,cli->inbuf,cli->timeout, 0); + len = client_receive_smb(cli, 0); if (len > 0) { /* it might be an oplock break request */ @@ -110,7 +112,6 @@ bool cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (len < 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = get_smb_read_error(); close(cli->fd); cli->fd = -1; return False; @@ -154,9 +155,10 @@ bool cli_receive_smb(struct cli_state *cli) ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { if (cli->timeout > 0) { - return read_socket_with_timeout(cli->fd, buffer, len, len, cli->timeout); + return read_socket_with_timeout(cli->fd, buffer, len, + len, cli->timeout, &cli->smb_rw_error); } else { - return read_data(cli->fd, buffer, len); + return read_data(cli->fd, buffer, len, &cli->smb_rw_error); } } @@ -174,7 +176,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) again: /* Read up to the size of a readX header reply. */ - len = client_receive_smb(cli->fd, cli->inbuf, cli->timeout, (smb_size - 4) + 24); + len = client_receive_smb(cli, (smb_size - 4) + 24); if (len > 0) { /* it might be an oplock break request */ @@ -240,7 +242,6 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) read_err: - set_smb_read_error(SMB_READ_ERROR); cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; -- cgit From d2cf97aeba14a4d336fb57b01f19bd5a08dcb003 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 13:24:54 -0800 Subject: Remove the explicit TALLOC_CTX * from cli_struct. Make us very explicit about how long a talloc ctx should last. Jeremy. (This used to be commit ba9e2be2b5a59684e854609f9d82ea1633448c62) --- source3/libsmb/clientgen.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ee1a0fe3db..1a6fb8f93f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -492,9 +492,6 @@ struct cli_state *cli_initialise(void) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL) - goto error; - memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); @@ -605,11 +602,6 @@ void cli_shutdown(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->mem_ctx) { - talloc_destroy(cli->mem_ctx); - cli->mem_ctx = NULL; - } - if (cli->fd != -1) { close(cli->fd); } -- cgit From addf598cde41d17ad4cf497a64b9a2b27e4028c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 22:17:16 +0100 Subject: Some C++ warnings (This used to be commit 5ab82d4f574f2a2e2761e9e414c66a70aeffb05d) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1a6fb8f93f..0544b3d879 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -471,7 +471,7 @@ struct cli_state *cli_initialise(void) cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = False; - cli->smb_rw_error = 0; + cli->smb_rw_error = SMB_READ_OK; cli->use_spnego = lp_client_use_spnego(); @@ -606,7 +606,7 @@ void cli_shutdown(struct cli_state *cli) close(cli->fd); } cli->fd = -1; - cli->smb_rw_error = 0; + cli->smb_rw_error = SMB_READ_OK; SAFE_FREE(cli); } -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/libsmb/clientgen.c | 108 ++++++++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 35 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0544b3d879..da225ebc24 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,6 +20,21 @@ #include "includes.h" +/******************************************************************* + Setup the word count and byte count for a client smb message. +********************************************************************/ + +int cli_set_message(char *buf,int num_words,int num_bytes,bool zero) +{ + if (zero && (num_words || num_bytes)) { + memset(buf + smb_size,'\0',num_words*2 + num_bytes); + } + SCVAL(buf,smb_wct,num_words); + SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); + return (smb_size + num_words*2 + num_bytes); +} + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -85,7 +100,7 @@ bool cli_receive_smb(struct cli_state *cli) /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) - return False; + return false; again: len = client_receive_smb(cli, 0); @@ -100,7 +115,7 @@ bool cli_receive_smb(struct cli_state *cli) int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); if (!cli->oplock_handler(cli, fnum, level)) { - return False; + return false; } } /* try to prevent loops */ @@ -114,7 +129,7 @@ bool cli_receive_smb(struct cli_state *cli) DEBUG(0, ("Receiving SMB: Server stopped responding\n")); close(cli->fd); cli->fd = -1; - return False; + return false; } if (!cli_check_sign_mac(cli)) { @@ -135,16 +150,16 @@ bool cli_receive_smb(struct cli_state *cli) * Set bad sig but don't close fd. */ cli->smb_rw_error = SMB_READ_BAD_SIG; - return True; + return true; } DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = SMB_READ_BAD_SIG; close(cli->fd); cli->fd = -1; - return False; + return false; }; - return True; + return true; } /**************************************************************************** @@ -164,6 +179,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) /**************************************************************************** Read a smb readX header. + We can only use this if encryption and signing are off. ****************************************************************************/ bool cli_receive_smb_readX_header(struct cli_state *cli) @@ -171,7 +187,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) ssize_t len, offset; if (cli->fd == -1) - return False; + return false; again: @@ -199,7 +215,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) if (cli->oplock_handler) { int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return False; + if (!cli->oplock_handler(cli, fnum, level)) return false; } /* try to prevent loops */ SCVAL(cli->inbuf,smb_com,0xFF); @@ -238,14 +254,14 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) } } - return True; + return true; read_err: cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; - return False; + return false; } static ssize_t write_socket(int fd, const char *buf, size_t len) @@ -272,32 +288,54 @@ bool cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out = cli->outbuf; + bool enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) - return False; + return false; cli_calculate_sign_mac(cli); - len = smb_len(cli->outbuf) + 4; + if (enc_on) { + NTSTATUS status = cli_encrypt_message(cli, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = SMB_WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return false; + } + } + + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } close(cli->fd); cli->fd = -1; cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } + + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } + /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) cli->mid++; - return True; + return true; } /**************************************************************************** @@ -347,7 +385,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, DEBUG(0,("Error writing %d extradata " "bytes to client. %d (%s)\n", (int)extradata,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } @@ -409,7 +447,7 @@ void cli_init_creds(struct cli_state *cli, const char *username, const char *dom fstrcpy(cli->user_name, username); pwd_set_cleartext(&cli->pwd, password); if (!*username) { - cli->pwd.null_pwd = True; + cli->pwd.null_pwd = true; } DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); @@ -424,16 +462,16 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) if (signing_state == Undefined) return; - if (signing_state == False) { - cli->sign_info.allow_smb_signing = False; - cli->sign_info.mandatory_signing = False; + if (signing_state == false) { + cli->sign_info.allow_smb_signing = false; + cli->sign_info.mandatory_signing = false; return; } - cli->sign_info.allow_smb_signing = True; + cli->sign_info.allow_smb_signing = true; if (signing_state == Required) - cli->sign_info.mandatory_signing = True; + cli->sign_info.mandatory_signing = true; } /**************************************************************************** @@ -470,7 +508,7 @@ struct cli_state *cli_initialise(void) cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; - cli->case_sensitive = False; + cli->case_sensitive = false; cli->smb_rw_error = SMB_READ_OK; cli->use_spnego = lp_client_use_spnego(); @@ -481,13 +519,13 @@ struct cli_state *cli_initialise(void) client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ if (getenv("CLI_FORCE_DOSERR")) - cli->force_dos_errors = True; + cli->force_dos_errors = true; if (lp_client_signing()) - cli->sign_info.allow_smb_signing = True; + cli->sign_info.allow_smb_signing = true; if (lp_client_signing() == Required) - cli->sign_info.mandatory_signing = True; + cli->sign_info.mandatory_signing = true; if (!cli->outbuf || !cli->inbuf) goto error; @@ -522,7 +560,7 @@ struct cli_state *cli_initialise(void) /**************************************************************************** External interface. Close an open named pipe over SMB. Free any authentication data. - Returns False if the cli_close call failed. + Returns false if the cli_close call failed. ****************************************************************************/ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) @@ -530,7 +568,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) bool ret; if (!cli) { - return False; + return false; } ret = cli_close(cli->cli, cli->fnum); @@ -650,15 +688,15 @@ bool cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { DEBUG(3, ("cli_send_keepalive: fd == -1\n")); - return False; + return false; } if (!send_keepalive(cli->fd)) { close(cli->fd); cli->fd = -1; DEBUG(0,("Error sending keepalive packet to client.\n")); - return False; + return false; } - return True; + return true; } /**************************************************************************** @@ -674,7 +712,7 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos, SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,length,True); + cli_set_message(cli->outbuf,1,length,true); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,num_echos); @@ -689,13 +727,13 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos, for (i=0; i Date: Wed, 26 Dec 2007 17:17:36 -0800 Subject: Encryption works better when you add the client decrypt code :-). Jeremy. (This used to be commit d67b2634068be9c69082a2b8c22c831aba371cd9) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index da225ebc24..ecef293d07 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -86,6 +86,17 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) break; } } + + if (cli_encryption_on(cli)) { + NTSTATUS status = cli_decrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status))); + cli->smb_rw_error = SMB_READ_BAD_DECRYPT; + return -1; + } + } + show_msg(cli->inbuf); return len; } -- cgit From a925a53f61ebdc6b4386b7c0853f2f87cbe2e166 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 16:42:31 +0100 Subject: read_socket_with_timeout has timeout=0 handling (This used to be commit 7101026061c470ed962267b43ac0aa67cc761a64) --- source3/libsmb/clientgen.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ecef293d07..042b3bdfb0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -180,12 +180,8 @@ bool cli_receive_smb(struct cli_state *cli) ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { - if (cli->timeout > 0) { - return read_socket_with_timeout(cli->fd, buffer, len, - len, cli->timeout, &cli->smb_rw_error); - } else { - return read_data(cli->fd, buffer, len, &cli->smb_rw_error); - } + return read_socket_with_timeout(cli->fd, buffer, len, len, + cli->timeout, &cli->smb_rw_error); } /**************************************************************************** -- cgit From 5e43eeb1b6eef7ea7a88ffc51a0a0535e9bd8023 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:41:48 +0100 Subject: Get rid of read_socket_with_timeout (This used to be commit f9c8ac83ff42137d2101d3bb17e5dcc3c3d70a8f) --- source3/libsmb/clientgen.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 042b3bdfb0..086c158ed2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -180,8 +180,28 @@ bool cli_receive_smb(struct cli_state *cli) ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { - return read_socket_with_timeout(cli->fd, buffer, len, len, - cli->timeout, &cli->smb_rw_error); + NTSTATUS status; + + set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); + + status = read_socket_with_timeout_ntstatus( + cli->fd, buffer, len, len, cli->timeout, NULL); + if (NT_STATUS_IS_OK(status)) { + return len; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(&cli->smb_rw_error, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(&cli->smb_rw_error, SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); + return -1; } /**************************************************************************** -- cgit From 6ddfa6ae7734ffdd26ac38478c27cc9d646ddadd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:43:50 +0100 Subject: read_socket_with_timeout_ntstatus->read_socket_with_timeout (This used to be commit 90554799afa42855c3e7b87dc632e67f0952f988) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 086c158ed2..7a7377f148 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -184,7 +184,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); - status = read_socket_with_timeout_ntstatus( + status = read_socket_with_timeout( cli->fd, buffer, len, len, cli->timeout, NULL); if (NT_STATUS_IS_OK(status)) { return len; -- cgit From 88c27f83d449fa20cba47cbf0a5dbaedc99859d8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:54:22 +0100 Subject: Convert receive_smb_raw to NTSTATUS (This used to be commit ba771bd858602452a9e58c3aab1336f2ac8a25ef) --- source3/libsmb/clientgen.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7a7377f148..3b7669f33e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -69,15 +69,36 @@ int cli_set_port(struct cli_state *cli, int port) static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) { - ssize_t len; + size_t len; for(;;) { - len = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, - maxlen, &cli->smb_rw_error); + NTSTATUS status; - if (len < 0) { + set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); + + status = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, + maxlen, &len); + if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("client_receive_smb failed\n")); show_msg(cli->inbuf); + + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(&cli->smb_rw_error, + SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(&cli->smb_rw_error, + SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); + return -1; + } + + if (len < 0) { return len; } -- cgit From 4b5169f590425334d9ae3f2b7be2201e2e0b747e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 11:54:37 +0100 Subject: Add explicit buf arg to cli_encrypt_message and cli_calculate_sign_mac (This used to be commit db6ae9ed2326e6cd68475375d049084cf1d5a98c) --- source3/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3b7669f33e..2fd304f135 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -343,10 +343,11 @@ bool cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return false; - cli_calculate_sign_mac(cli); + cli_calculate_sign_mac(cli, cli->outbuf); if (enc_on) { - NTSTATUS status = cli_encrypt_message(cli, &buf_out); + NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, + &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; -- cgit From b9f7dd2909487f8e306774ee0475f8b20331a866 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 23:16:37 +0100 Subject: Add explicit buf arg to cli_check_sign_mac (This used to be commit ffc1c8cc03e6bad40ed2be91392074b4f038a1bf) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2fd304f135..ccd1cc67d5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -164,7 +164,7 @@ bool cli_receive_smb(struct cli_state *cli) return false; } - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, cli->inbuf)) { /* * If we get a signature failure in sessionsetup, then * the server sometimes just reflects the sent signature -- cgit From 57a9fba097a5f5af7833eaf4355667dbfacaec43 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 14:03:38 +0100 Subject: Make cli_struct a talloc parent (This used to be commit e69244a5c8c7c6b7c1897adc4b4b1cfdfc7a7999) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ccd1cc67d5..592f050e90 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -537,7 +537,7 @@ struct cli_state *cli_initialise(void) return NULL; } - cli = SMB_MALLOC_P(struct cli_state); + cli = talloc(NULL, struct cli_state); if (!cli) { return NULL; } @@ -695,7 +695,7 @@ void cli_shutdown(struct cli_state *cli) cli->fd = -1; cli->smb_rw_error = SMB_READ_OK; - SAFE_FREE(cli); + TALLOC_FREE(cli); } /**************************************************************************** -- cgit From be4a76a861f3a152f1d1aebf937b06e1628f2d55 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 14:04:54 +0100 Subject: Add cli_setup_packet_buf This is == cli_setup_packet but takes an explicit buffer argument (This used to be commit f64b46dc278899c3449cfd3dbb614aadcf5614d3) --- source3/libsmb/clientgen.c | 54 +++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 22 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 592f050e90..64191239d3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -450,31 +450,41 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, Setup basics in a outgoing packet. ****************************************************************************/ -void cli_setup_packet(struct cli_state *cli) +void cli_setup_packet_buf(struct cli_state *cli, char *buf) { + uint16 flags2; cli->rap_error = 0; - SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->vuid); - SSVAL(cli->outbuf,smb_mid,cli->mid); - if (cli->protocol > PROTOCOL_CORE) { - uint16 flags2; - if (cli->case_sensitive) { - SCVAL(cli->outbuf,smb_flg,0x0); - } else { - /* Default setting, case insensitive. */ - SCVAL(cli->outbuf,smb_flg,0x8); - } - flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) - flags2 |= FLAGS2_UNICODE_STRINGS; - if ((cli->capabilities & CAP_DFS) && cli->dfsroot) - flags2 |= FLAGS2_DFS_PATHNAMES; - if (cli->capabilities & CAP_STATUS32) - flags2 |= FLAGS2_32_BIT_ERROR_CODES; - if (cli->use_spnego) - flags2 |= FLAGS2_EXTENDED_SECURITY; - SSVAL(cli->outbuf,smb_flg2, flags2); + SIVAL(buf,smb_rcls,0); + SSVAL(buf,smb_pid,cli->pid); + memset(buf+smb_pidhigh, 0, 12); + SSVAL(buf,smb_uid,cli->vuid); + SSVAL(buf,smb_mid,cli->mid); + + if (cli->protocol <= PROTOCOL_CORE) { + return; + } + + if (cli->case_sensitive) { + SCVAL(buf,smb_flg,0x0); + } else { + /* Default setting, case insensitive. */ + SCVAL(buf,smb_flg,0x8); } + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + if (cli->capabilities & CAP_UNICODE) + flags2 |= FLAGS2_UNICODE_STRINGS; + if ((cli->capabilities & CAP_DFS) && cli->dfsroot) + flags2 |= FLAGS2_DFS_PATHNAMES; + if (cli->capabilities & CAP_STATUS32) + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + if (cli->use_spnego) + flags2 |= FLAGS2_EXTENDED_SECURITY; + SSVAL(buf,smb_flg2, flags2); +} + +void cli_setup_packet(struct cli_state *cli) +{ + cli_setup_packet_buf(cli, cli->outbuf); } /**************************************************************************** -- cgit From b46d340fd5d7e88684ac77000e17c1899ff608b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 18:17:13 +0200 Subject: Refactoring: Make struct rpc_pipe_client its own talloc parent (This used to be commit a6d74a5a562b54f0b36934965f545fdeb1e8b34a) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 64191239d3..860cb948ac 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -650,7 +650,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) cli->pipe_name, cli->cli->desthost )); DLIST_REMOVE(cli->cli->pipe_list, cli); - talloc_destroy(cli->mem_ctx); + talloc_destroy(cli); return ret; } -- cgit From 2a2188591b5ed922d09dc723adcf10f8b8f5e5a0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 21:56:43 +0200 Subject: Add "desthost" to rpc_pipe_client This reduces the dependency on cli_state (This used to be commit 783afab9c891dd7bcb78895b2a639b6f3a0edf5b) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 860cb948ac..ef2c2639cd 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -638,7 +638,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) "to machine %s. Error was %s\n", cli->pipe_name, (int) cli->fnum, - cli->cli->desthost, + cli->desthost, cli_errstr(cli->cli))); } @@ -647,7 +647,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) } DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", - cli->pipe_name, cli->cli->desthost )); + cli->pipe_name, cli->desthost )); DLIST_REMOVE(cli->cli->pipe_list, cli); talloc_destroy(cli); -- cgit From e73e8297f5484b6c7f525917679414c09a145cf0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 13:51:46 +0200 Subject: Replace cli_rpc_pipe_close by a talloc destructor on rpc_pipe_struct (This used to be commit 99fc3283c4ecc791f5a242bd1983b4352ce3e6cf) --- source3/libsmb/clientgen.c | 48 +++++----------------------------------------- 1 file changed, 5 insertions(+), 43 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ef2c2639cd..e64b6fa278 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -616,55 +616,17 @@ struct cli_state *cli_initialise(void) return NULL; } -/**************************************************************************** - External interface. - Close an open named pipe over SMB. Free any authentication data. - Returns false if the cli_close call failed. - ****************************************************************************/ - -bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) -{ - bool ret; - - if (!cli) { - return false; - } - - ret = cli_close(cli->cli, cli->fnum); - - if (!ret) { - DEBUG(1,("cli_rpc_pipe_close: cli_close failed on pipe %s, " - "fnum 0x%x " - "to machine %s. Error was %s\n", - cli->pipe_name, - (int) cli->fnum, - cli->desthost, - cli_errstr(cli->cli))); - } - - if (cli->auth.cli_auth_data_free_func) { - (*cli->auth.cli_auth_data_free_func)(&cli->auth); - } - - DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", - cli->pipe_name, cli->desthost )); - - DLIST_REMOVE(cli->cli->pipe_list, cli); - talloc_destroy(cli); - return ret; -} - /**************************************************************************** Close all pipes open on this session. ****************************************************************************/ void cli_nt_pipes_close(struct cli_state *cli) { - struct rpc_pipe_client *cp, *next; - - for (cp = cli->pipe_list; cp; cp = next) { - next = cp->next; - cli_rpc_pipe_close(cp); + while (cli->pipe_list != NULL) { + /* + * No TALLOC_FREE here! + */ + talloc_free(cli->pipe_list); } } -- cgit From d36434f31268b75040311352f23c92c9a61e8cda Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 May 2008 09:31:42 -0700 Subject: Security fix for CVE-2008-1105: Boundary failure when parsing SMB responses can result in a buffer overrun. Jeremy. (This used to be commit 23b825e9d2c74c5b940cf4d3aa56c18692259972) --- source3/libsmb/clientgen.c | 94 ++-------------------------------------------- 1 file changed, 3 insertions(+), 91 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e64b6fa278..60ec632b83 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -57,8 +57,7 @@ int cli_set_port(struct cli_state *cli, int port) } /**************************************************************************** - Read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + Read an smb from a fd ignoring all keepalive packets. The timeout is in milliseconds This is exactly the same as receive_smb except that it never returns @@ -76,8 +75,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); - status = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, - maxlen, &len); + status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize, + cli->timeout, maxlen, &len); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("client_receive_smb failed\n")); show_msg(cli->inbuf); @@ -225,93 +224,6 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) return -1; } -/**************************************************************************** - Read a smb readX header. - We can only use this if encryption and signing are off. -****************************************************************************/ - -bool cli_receive_smb_readX_header(struct cli_state *cli) -{ - ssize_t len, offset; - - if (cli->fd == -1) - return false; - - again: - - /* Read up to the size of a readX header reply. */ - len = client_receive_smb(cli, (smb_size - 4) + 24); - - if (len > 0) { - /* it might be an oplock break request */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && - CVAL(cli->inbuf,smb_com) == SMBlockingX && - SVAL(cli->inbuf,smb_vwv6) == 0 && - SVAL(cli->inbuf,smb_vwv7) == 0) { - ssize_t total_len = smb_len(cli->inbuf); - - if (total_len > CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN) { - goto read_err; - } - - /* Read the rest of the data. */ - if ((total_len - len > 0) && - !cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { - goto read_err; - } - - if (cli->oplock_handler) { - int fnum = SVAL(cli->inbuf,smb_vwv2); - unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return false; - } - /* try to prevent loops */ - SCVAL(cli->inbuf,smb_com,0xFF); - goto again; - } - } - - /* If it's not the above size it probably was an error packet. */ - - if ((len == (smb_size - 4) + 24) && !cli_is_error(cli)) { - /* Check it's a non-chained readX reply. */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || - (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || - (CVAL(cli->inbuf,smb_com) != SMBreadX)) { - /* - * We're not coping here with asnyc replies to - * other calls. Punt here - we need async client - * libs for this. - */ - goto read_err; - } - - /* - * We know it's a readX reply - ensure we've read the - * padding bytes also. - */ - - offset = SVAL(cli->inbuf,smb_vwv6); - if (offset > len) { - ssize_t ret; - size_t padbytes = offset - len; - ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); - if (ret != padbytes) { - goto read_err; - } - } - } - - return true; - - read_err: - - cli->smb_rw_error = SMB_READ_ERROR; - close(cli->fd); - cli->fd = -1; - return false; -} - static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; -- cgit From 4a09c5a09f791738453947f07abe8d0f100fe53d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Jul 2008 15:39:41 -0700 Subject: Two more fixes from Jim Brown for SGI compiler warnings. Jeremy. (This used to be commit d85cbdbe296ec6de5bdbd66a90ca41345f55c837) --- source3/libsmb/clientgen.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 60ec632b83..2c0950de03 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -97,7 +97,12 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) return -1; } - if (len < 0) { + /* + * I don't believe len can be < 0 with NT_STATUS_OK + * returned above, but this check doesn't hurt. JRA. + */ + + if ((ssize_t)len < 0) { return len; } -- cgit From 228a12681bc7e6eb5bddb75b3b97a74c5eef1c3a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 27 Aug 2008 19:30:57 +0200 Subject: Add async smbecho client support (This used to be commit c1d645fbe39433541d8bfe6b818c855cee318dc5) --- source3/libsmb/clientgen.c | 166 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 27 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2c0950de03..239ba470a9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -637,41 +637,153 @@ bool cli_send_keepalive(struct cli_state *cli) return true; } -/**************************************************************************** - Send/receive a SMBecho command: ping the server -****************************************************************************/ +/** + * @brief: Collect a echo reply + * @param[in] req The corresponding async request + * + * There might be more than one echo reply. This helper pulls the reply out of + * the data stream. If all expected replies have arrived, declare the + * async_req done. + */ + +static void cli_echo_recv_helper(struct async_req *req) +{ + struct cli_request *cli_req; + uint8_t wct; + uint16_t *vwv; + uint16_t num_bytes; + uint8_t *bytes; + NTSTATUS status; + + status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + cli_req = cli_request_get(req); + + if ((num_bytes != cli_req->data.echo.data.length) + || (memcmp(cli_req->data.echo.data.data, bytes, + num_bytes) != 0)) { + async_req_error(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + cli_req->data.echo.num_echos -= 1; -bool cli_echo(struct cli_state *cli, uint16 num_echos, - unsigned char *data, size_t length) + if (cli_req->data.echo.num_echos == 0) { + client_set_trans_sign_state_off(cli_req->cli, cli_req->mid); + async_req_done(req); + return; + } + + return; +} + +/** + * @brief Send SMBEcho requests + * @param[in] mem_ctx The memory context to put the async_req on + * @param[in] ev The event context that will call us back + * @param[in] cli The connection to send the echo to + * @param[in] num_echos How many times do we want to get the reply? + * @param[in] data The data we want to get back + * @retval The async request + */ + +struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, uint16_t num_echos, + DATA_BLOB data) { - char *p; - int i; + uint16_t vwv[1]; + uint8_t *data_copy; + struct async_req *result; + struct cli_request *req; - SMB_ASSERT(length < 1024); + SSVAL(vwv, 0, num_echos); - memset(cli->outbuf,'\0',smb_size); - cli_set_message(cli->outbuf,1,length,true); - SCVAL(cli->outbuf,smb_com,SMBecho); - SSVAL(cli->outbuf,smb_tid,65535); - SSVAL(cli->outbuf,smb_vwv0,num_echos); - cli_setup_packet(cli); - p = smb_buf(cli->outbuf); - memcpy(p, data, length); - p += length; + data_copy = (uint8_t *)talloc_memdup(mem_ctx, data.data, data.length); + if (data_copy == NULL) { + return NULL; + } - cli_setup_bcc(cli, p); + result = cli_request_send(mem_ctx, ev, cli, SMBecho, 0, 1, vwv, + data.length, data.data); + if (result == NULL) { + TALLOC_FREE(data_copy); + return NULL; + } + req = cli_request_get(result); - cli_send_smb(cli); + client_set_trans_sign_state_on(cli, req->mid); - for (i=0; idata.echo.num_echos = num_echos; + req->data.echo.data.data = talloc_move(req, &data_copy); + req->data.echo.data.length = data.length; - if (cli_is_error(cli)) { - return false; - } + req->recv_helper.fn = cli_echo_recv_helper; + + return result; +} + +/** + * Get the result out from an echo request + * @param[in] req The async_req from cli_echo_send + * @retval Did the server reply correctly? + */ + +NTSTATUS cli_echo_recv(struct async_req *req) +{ + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; } - return true; + return NT_STATUS_OK; +} + +/** + * @brief Send/Receive SMBEcho requests + * @param[in] mem_ctx The memory context to put the async_req on + * @param[in] ev The event context that will call us back + * @param[in] cli The connection to send the echo to + * @param[in] num_echos How many times do we want to get the reply? + * @param[in] data The data we want to get back + * @retval Did the server reply correctly? + */ + +NTSTATUS cli_echo(struct cli_state *cli, uint16_t num_echos, DATA_BLOB data) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli->fd_event != NULL) { + /* + * Can't use sync call while an async call is in flight + */ + cli_set_error(cli, NT_STATUS_INVALID_PARAMETER); + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = cli_echo_send(frame, ev, cli, num_echos, data); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = cli_echo_recv(req); + + fail: + TALLOC_FREE(frame); + return status; } -- cgit From f294f51bf0d136208fee1be343684ea890a499d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Aug 2008 15:44:14 +0200 Subject: Remove cli_request_get() req->private_data==NULL at this point is definitely a bug. (This used to be commit ce3dc9f616cafc1289a94ac7cae0beca967d836e) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 239ba470a9..9d65fb4e94 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -661,7 +661,7 @@ static void cli_echo_recv_helper(struct async_req *req) return; } - cli_req = cli_request_get(req); + cli_req = talloc_get_type_abort(req->private_data, struct cli_request); if ((num_bytes != cli_req->data.echo.data.length) || (memcmp(cli_req->data.echo.data.data, bytes, @@ -713,7 +713,7 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, TALLOC_FREE(data_copy); return NULL; } - req = cli_request_get(result); + req = talloc_get_type_abort(result->private_data, struct cli_request); client_set_trans_sign_state_on(cli, req->mid); -- cgit