2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 extern pstring myname;
35 pstring password = "";
37 pstring workgroup=WORKGROUP;
38 BOOL got_pass = False;
39 BOOL connect_as_printer = False;
40 BOOL connect_as_ipc = False;
45 extern pstring user_socket_options;
47 /* 30 second timeout on most commands */
48 #define CLIENT_TIMEOUT (30*1000)
49 #define SHORT_TIMEOUT (5*1000)
53 int max_protocol = PROTOCOL_NT1;
55 BOOL readbraw_supported = False;
56 BOOL writebraw_supported = False;
58 extern int DEBUGLEVEL;
66 int max_xmit = BUFFER_SIZE;
70 struct in_addr dest_ip;
77 /****************************************************************************
78 setup basics in a outgoing packet
79 ****************************************************************************/
80 void cli_setup_pkt(char *outbuf)
82 SSVAL(outbuf,smb_pid,pid);
83 SSVAL(outbuf,smb_uid,uid);
84 SSVAL(outbuf,smb_mid,mid);
85 if (Protocol > PROTOCOL_CORE)
87 SCVAL(outbuf,smb_flg,0x8);
88 SSVAL(outbuf,smb_flg2,0x1);
92 /****************************************************************************
93 receive a SMB trans or trans2 response allocating the necessary memory
94 ****************************************************************************/
95 BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
96 int *param_len, char **data,char **param)
100 int this_data,this_param;
102 *data_len = *param_len = 0;
104 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
108 if (CVAL(inbuf,smb_com) != trans)
110 DEBUG(0,("Expected %s response, got command 0x%02x\n",
111 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
114 if (CVAL(inbuf,smb_rcls) != 0)
117 /* parse out the lengths */
118 total_data = SVAL(inbuf,smb_tdrcnt);
119 total_param = SVAL(inbuf,smb_tprcnt);
122 *data = Realloc(*data,total_data);
123 *param = Realloc(*param,total_param);
127 this_data = SVAL(inbuf,smb_drcnt);
128 this_param = SVAL(inbuf,smb_prcnt);
130 memcpy(*data + SVAL(inbuf,smb_drdisp),
131 smb_base(inbuf) + SVAL(inbuf,smb_droff),
134 memcpy(*param + SVAL(inbuf,smb_prdisp),
135 smb_base(inbuf) + SVAL(inbuf,smb_proff),
137 *data_len += this_data;
138 *param_len += this_param;
140 /* parse out the total lengths again - they can shrink! */
141 total_data = SVAL(inbuf,smb_tdrcnt);
142 total_param = SVAL(inbuf,smb_tprcnt);
144 if (total_data <= *data_len && total_param <= *param_len)
147 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
151 if (CVAL(inbuf,smb_com) != trans)
153 DEBUG(0,("Expected %s response, got command 0x%02x\n",
154 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
157 if (CVAL(inbuf,smb_rcls) != 0)
164 /****************************************************************************
165 send a session request
166 ****************************************************************************/
167 BOOL cli_send_session_request(char *inbuf, char *outbuf)
172 /* send a session request (RFC 8002) */
174 strcpy(dest,desthost);
175 p = strchr(dest,'.');
178 /* put in the destination name */
180 name_mangle(dest,p,name_type);
185 name_mangle(myname,p,0);
188 /* setup the packet length */
189 _smb_setlen(outbuf,len);
190 CVAL(outbuf,0) = 0x81;
192 send_smb(Client,outbuf);
193 DEBUG(5,("Sent session request\n"));
195 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
197 if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
199 /* For information, here is the response structure.
200 * We do the byte-twiddling to for portability.
201 struct RetargetResponse{
210 int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
211 /* SESSION RETARGET */
212 putip((char *)&dest_ip,inbuf+4);
215 Client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
219 DEBUG(5,("Retargeted\n"));
221 set_socket_options(Client,user_socket_options);
224 return cli_send_session_request(inbuf,outbuf);
225 } /* C. Hoch 9/14/95 End */
228 if (CVAL(inbuf,0) != 0x82)
230 int ecode = CVAL(inbuf,4);
231 DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
232 CVAL(inbuf,0),ecode,myname,desthost));
236 DEBUG(0,("Not listening on called name\n"));
237 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
238 DEBUG(0,("You may find the -I option useful for this\n"));
241 DEBUG(0,("Not listening for calling name\n"));
242 DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
243 DEBUG(0,("You may find the -n option useful for this\n"));
246 DEBUG(0,("Called name not present\n"));
247 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
248 DEBUG(0,("You may find the -I option useful for this\n"));
251 DEBUG(0,("Called name present, but insufficient resources\n"));
252 DEBUG(0,("Perhaps you should try again later?\n"));
255 DEBUG(0,("Unspecified error 0x%X\n",ecode));
256 DEBUG(0,("Your server software is being unfriendly\n"));
271 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
272 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
273 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
274 {PROTOCOL_LANMAN1,"LANMAN1.0"},
275 {PROTOCOL_LANMAN2,"LM1.2X002"},
276 {PROTOCOL_LANMAN2,"Samba"},
277 {PROTOCOL_NT1,"NT LM 0.12"},
278 {PROTOCOL_NT1,"NT LANMAN 1.0"},
282 /****************************************************************************
284 ****************************************************************************/
285 BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup)
287 BOOL was_null = (!inbuf && !outbuf);
289 time_t servertime = 0;
290 extern int serverzone;
301 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
302 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
306 if (connect_as_printer)
312 if (start_session && !cli_send_session_request(inbuf,outbuf))
322 bzero(outbuf,smb_size);
324 /* setup the protocol strings */
328 for (plength=0,numprots=0;
329 prots[numprots].name && prots[numprots].prot<=max_protocol;
331 plength += strlen(prots[numprots].name)+2;
333 set_message(outbuf,0,plength,True);
337 prots[numprots].name && prots[numprots].prot<=max_protocol;
341 strcpy(p,prots[numprots].name);
346 CVAL(outbuf,smb_com) = SMBnegprot;
347 cli_setup_pkt(outbuf);
349 CVAL(smb_buf(outbuf),0) = 2;
351 send_smb(Client,outbuf);
352 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
356 if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
358 DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
359 myname,desthost,smb_errstr(inbuf)));
368 Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
371 if (Protocol < PROTOCOL_NT1) {
372 sec_mode = SVAL(inbuf,smb_vwv1);
373 max_xmit = SVAL(inbuf,smb_vwv2);
374 sesskey = IVAL(inbuf,smb_vwv6);
375 serverzone = SVALS(inbuf,smb_vwv10)*60;
376 /* this time is converted to GMT by make_unix_date */
377 servertime = make_unix_date(inbuf+smb_vwv8);
378 if (Protocol >= PROTOCOL_COREPLUS) {
379 readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
380 writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
382 crypt_len = smb_buflen(inbuf);
383 memcpy(cryptkey,smb_buf(inbuf),8);
384 DEBUG(5,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
385 max_vcs = SVAL(inbuf,smb_vwv4);
386 DEBUG(5,("max vcs %d\n",max_vcs));
387 DEBUG(5,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
390 sec_mode = CVAL(inbuf,smb_vwv1);
391 max_xmit = IVAL(inbuf,smb_vwv3+1);
392 sesskey = IVAL(inbuf,smb_vwv7+1);
393 serverzone = SVALS(inbuf,smb_vwv15+1)*60;
394 /* this time arrives in real GMT */
395 servertime = interpret_long_date(inbuf+smb_vwv11+1);
396 crypt_len = CVAL(inbuf,smb_vwv16+1);
397 memcpy(cryptkey,smb_buf(inbuf),8);
398 if (IVAL(inbuf,smb_vwv9+1) & 1)
399 readbraw_supported = writebraw_supported = True;
400 DEBUG(5,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
401 max_vcs = SVAL(inbuf,smb_vwv2+1);
402 DEBUG(5,("max vcs %d\n",max_vcs));
403 DEBUG(5,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
404 DEBUG(5,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
407 DEBUG(5,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
408 DEBUG(5,("max xmt %d\n",max_xmit));
409 DEBUG(5,("Got %d byte crypt key\n",crypt_len));
410 DEBUG(5,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
412 doencrypt = ((sec_mode & 2) != 0);
415 static BOOL done_time = False;
417 DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
418 asctime(LocalTime(&servertime)),
419 -(double)(serverzone/3600.0)));
429 pass = (char *)getpass("Password: ");
431 if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
434 int passlen = strlen(pass)+1;
438 if (doencrypt && *pass) {
439 DEBUG(5,("Using encrypted passwords\n"));
441 SMBencrypt(pass,cryptkey,pword);
447 /* if in share level security then don't send a password now */
448 if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;}
450 /* send a session setup command */
451 bzero(outbuf,smb_size);
453 if (Protocol < PROTOCOL_NT1) {
454 set_message(outbuf,10,1 + strlen(username) + passlen,True);
455 CVAL(outbuf,smb_com) = SMBsesssetupX;
456 cli_setup_pkt(outbuf);
458 CVAL(outbuf,smb_vwv0) = 0xFF;
459 SSVAL(outbuf,smb_vwv2,max_xmit);
460 SSVAL(outbuf,smb_vwv3,2);
461 SSVAL(outbuf,smb_vwv4,max_vcs-1);
462 SIVAL(outbuf,smb_vwv5,sesskey);
463 SSVAL(outbuf,smb_vwv7,passlen);
465 memcpy(p,pword,passlen);
469 if (!doencrypt) passlen--;
471 set_message(outbuf,13,0,True);
472 CVAL(outbuf,smb_com) = SMBsesssetupX;
473 cli_setup_pkt(outbuf);
475 CVAL(outbuf,smb_vwv0) = 0xFF;
476 SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
477 SSVAL(outbuf,smb_vwv3,2);
478 SSVAL(outbuf,smb_vwv4,getpid());
479 SIVAL(outbuf,smb_vwv5,sesskey);
480 SSVAL(outbuf,smb_vwv7,passlen);
481 SSVAL(outbuf,smb_vwv8,0);
483 memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
484 strcpy(p,username);p = skip_string(p,1);
485 strcpy(p,workgroup);p = skip_string(p,1);
486 strcpy(p,"Unix");p = skip_string(p,1);
487 strcpy(p,"Samba");p = skip_string(p,1);
488 set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
491 send_smb(Client,outbuf);
492 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
496 if (CVAL(inbuf,smb_rcls) != 0)
499 ((CVAL(inbuf,smb_rcls) == ERRDOS &&
500 SVAL(inbuf,smb_err) == ERRnoaccess) ||
501 (CVAL(inbuf,smb_rcls) == ERRSRV &&
502 SVAL(inbuf,smb_err) == ERRbadpw)))
505 DEBUG(5,("resending login\n"));
509 DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
510 username,myname,desthost,smb_errstr(inbuf)));
511 DEBUG(0,("You might find the -U or -n options useful\n"));
512 DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
513 DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
522 if (Protocol >= PROTOCOL_NT1) {
523 char *domain,*os,*lanman;
526 lanman = skip_string(os,1);
527 domain = skip_string(lanman,1);
528 if (*domain || *os || *lanman)
529 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
532 /* use the returned uid from now on */
533 if (SVAL(inbuf,smb_uid) != uid)
534 DEBUG(5,("Server gave us a UID of %d. We gave %d\n",
535 SVAL(inbuf,smb_uid),uid));
536 uid = SVAL(inbuf,smb_uid);
539 /* now we've got a connection - send a tcon message */
540 bzero(outbuf,smb_size);
542 if (strncmp(service,"\\\\",2) != 0)
544 DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
545 DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
552 int passlen = strlen(pass)+1;
557 if (doencrypt && *pass) {
559 SMBencrypt(pass,cryptkey,pword);
563 /* if in user level security then don't send a password now */
564 if ((sec_mode & 1)) {
565 strcpy(pword, ""); passlen=1;
568 set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
569 CVAL(outbuf,smb_com) = SMBtconX;
570 cli_setup_pkt(outbuf);
572 SSVAL(outbuf,smb_vwv0,0xFF);
573 SSVAL(outbuf,smb_vwv3,passlen);
576 memcpy(p,pword,passlen);
579 p = skip_string(p,1);
583 send_smb(Client,outbuf);
584 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
586 /* trying again with a blank password */
587 if (CVAL(inbuf,smb_rcls) != 0 &&
588 (int)strlen(pass) > 0 &&
590 Protocol >= PROTOCOL_LANMAN1)
592 DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
597 if (CVAL(inbuf,smb_rcls) != 0)
599 DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
600 DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
601 DEBUG(0,("Some servers insist that these be in uppercase\n"));
611 max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
613 max_xmit = BUFFER_SIZE - 4;
615 cnum = SVAL(inbuf,smb_tid);
617 DEBUG(5,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
628 /****************************************************************************
629 send a logout command
630 ****************************************************************************/
631 void cli_send_logout(void)
633 pstring inbuf,outbuf;
635 bzero(outbuf,smb_size);
636 set_message(outbuf,0,0,True);
637 CVAL(outbuf,smb_com) = SMBtdis;
638 SSVAL(outbuf,smb_tid,cnum);
639 cli_setup_pkt(outbuf);
641 send_smb(Client,outbuf);
642 receive_smb(Client,inbuf,SHORT_TIMEOUT);
644 if (CVAL(inbuf,smb_rcls) != 0)
646 DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
658 /****************************************************************************
660 ****************************************************************************/
661 BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
662 int *rdrcnt, char *param,char *data, char **rparam,char **rdata)
664 static char *inbuf=NULL;
665 static char *outbuf=NULL;
667 if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
668 if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
670 cli_send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
675 return (cli_receive_trans_response(inbuf,SMBtrans,
680 /****************************************************************************
681 send a SMB trans or trans2 request
682 ****************************************************************************/
683 BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags,
684 char *data,char *param,uint16 *setup, int ldata,int lparam,
685 int lsetup,int mdata,int mparam,int msetup)
688 int this_ldata,this_lparam;
689 int tot_data=0,tot_param=0;
690 char *outdata,*outparam;
694 this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
695 this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
697 bzero(outbuf,smb_size);
698 set_message(outbuf,14+lsetup,0,True);
699 CVAL(outbuf,smb_com) = trans;
700 SSVAL(outbuf,smb_tid,cnum);
701 cli_setup_pkt(outbuf);
703 outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
704 outdata = outparam+this_lparam;
706 /* primary request */
707 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
708 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
709 SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
710 SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
711 SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
712 SSVAL(outbuf,smb_flags,flags); /* flags */
713 SIVAL(outbuf,smb_timeout,0); /* timeout */
714 SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
715 SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
716 SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
717 SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
718 SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
719 for (i=0;i<lsetup;i++) /* setup[] */
720 SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
723 strcpy(p,name); /* name[] */
726 *p++ = 0; /* put in a null smb_name */
727 *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
729 if (this_lparam) /* param[] */
730 memcpy(outparam,param,this_lparam);
731 if (this_ldata) /* data[] */
732 memcpy(outdata,data,this_ldata);
733 set_message(outbuf,14+lsetup, /* wcnt, bcc */
734 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
737 send_smb(Client,outbuf);
739 if (this_ldata < ldata || this_lparam < lparam)
741 /* receive interim response */
742 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
744 DEBUG(0,("%s request failed (%s)\n",
745 trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
749 tot_data = this_ldata;
750 tot_param = this_lparam;
752 while (tot_data < ldata || tot_param < lparam)
754 this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
755 this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
757 set_message(outbuf,trans==SMBtrans?8:9,0,True);
758 CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
760 outparam = smb_buf(outbuf);
761 outdata = outparam+this_lparam;
763 /* secondary request */
764 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
765 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
766 SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
767 SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
768 SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
769 SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
770 SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
771 SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
772 if (trans==SMBtrans2)
773 SSVAL(outbuf,smb_sfid,fid); /* fid */
774 if (this_lparam) /* param[] */
775 memcpy(outparam,param,this_lparam);
776 if (this_ldata) /* data[] */
777 memcpy(outdata,data,this_ldata);
778 set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
779 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
782 send_smb(Client,outbuf);
784 tot_data += this_ldata;
785 tot_param += this_lparam;
793 /****************************************************************************
794 open the client sockets
795 ****************************************************************************/
796 BOOL cli_open_sockets(int port)
798 static int last_port;
803 if (port == 0) port=last_port;
814 strcpy(service2,service);
815 host = strtok(service2,"\\/");
816 strcpy(desthost,host);
819 DEBUG(5,("Opening sockets\n"));
822 get_myname(myname,NULL);
829 if ((hp = Get_Hostbyname(host)) == 0)
831 DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
835 putip((char *)&dest_ip,(char *)hp->h_addr);
838 Client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
842 DEBUG(5,("Connected\n"));
844 set_socket_options(Client,user_socket_options);
849 /****************************************************************************
850 close and open the connection again
851 ****************************************************************************/
852 BOOL cli_reopen_connection(char *inbuf,char *outbuf)
854 static int open_count=0;
858 if (open_count>5) return(False);
860 DEBUG(1,("Trying to re-open connection\n"));
862 set_message(outbuf,0,0,True);
863 SCVAL(outbuf,smb_com,SMBtdis);
864 SSVAL(outbuf,smb_tid,cnum);
865 cli_setup_pkt(outbuf);
867 send_smb(Client,outbuf);
868 receive_smb(Client,inbuf,SHORT_TIMEOUT);
871 if (!cli_open_sockets(0)) return(False);
873 return(cli_send_login(inbuf,outbuf,True,True));
876 /* error code stuff - put together by Merik Karman
877 merik@blackadder.dsh.oz.au */
886 /* Dos Error Messages */
887 err_code_struct dos_msgs[] = {
888 {"ERRbadfunc",1,"Invalid function."},
889 {"ERRbadfile",2,"File not found."},
890 {"ERRbadpath",3,"Directory invalid."},
891 {"ERRnofids",4,"No file descriptors available"},
892 {"ERRnoaccess",5,"Access denied."},
893 {"ERRbadfid",6,"Invalid file handle."},
894 {"ERRbadmcb",7,"Memory control blocks destroyed."},
895 {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
896 {"ERRbadmem",9,"Invalid memory block address."},
897 {"ERRbadenv",10,"Invalid environment."},
898 {"ERRbadformat",11,"Invalid format."},
899 {"ERRbadaccess",12,"Invalid open mode."},
900 {"ERRbaddata",13,"Invalid data."},
901 {"ERR",14,"reserved."},
902 {"ERRbaddrive",15,"Invalid drive specified."},
903 {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
904 {"ERRdiffdevice",17,"Not same device."},
905 {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
906 {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
907 {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
908 {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
909 {"ERRbadpipe",230,"Pipe invalid."},
910 {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
911 {"ERRpipeclosing",232,"Pipe close in progress."},
912 {"ERRnotconnected",233,"No process on other end of pipe."},
913 {"ERRmoredata",234,"There is more data to be returned."},
916 /* Server Error Messages */
917 err_code_struct server_msgs[] = {
918 {"ERRerror",1,"Non-specific error code."},
919 {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
920 {"ERRbadtype",3,"reserved."},
921 {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."},
922 {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
923 {"ERRinvnetname",6,"Invalid network name in tree connect."},
924 {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
925 {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
926 {"ERRqtoobig",50,"Print queue full -- no space."},
927 {"ERRqeof",51,"EOF on print queue dump."},
928 {"ERRinvpfid",52,"Invalid print file FID."},
929 {"ERRsmbcmd",64,"The server did not recognize the command received."},
930 {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
931 {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
932 {"ERRreserved",68,"reserved."},
933 {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
934 {"ERRreserved",70,"reserved."},
935 {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
936 {"ERRpaused",81,"Server is paused."},
937 {"ERRmsgoff",82,"Not receiving messages."},
938 {"ERRnoroom",83,"No room to buffer message."},
939 {"ERRrmuns",87,"Too many remote user names."},
940 {"ERRtimeout",88,"Operation timed out."},
941 {"ERRnoresource",89,"No resources currently available for request."},
942 {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
943 {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
944 {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
945 {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
946 {"ERRcontmpx",252,"Continue in MPX mode."},
947 {"ERRreserved",253,"reserved."},
948 {"ERRreserved",254,"reserved."},
949 {"ERRnosupport",0xFFFF,"Function not supported."},
952 /* Hard Error Messages */
953 err_code_struct hard_msgs[] = {
954 {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
955 {"ERRbadunit",20,"Unknown unit."},
956 {"ERRnotready",21,"Drive not ready."},
957 {"ERRbadcmd",22,"Unknown command."},
958 {"ERRdata",23,"Data error (CRC)."},
959 {"ERRbadreq",24,"Bad request structure length."},
960 {"ERRseek",25 ,"Seek error."},
961 {"ERRbadmedia",26,"Unknown media type."},
962 {"ERRbadsector",27,"Sector not found."},
963 {"ERRnopaper",28,"Printer out of paper."},
964 {"ERRwrite",29,"Write fault."},
965 {"ERRread",30,"Read fault."},
966 {"ERRgeneral",31,"General failure."},
967 {"ERRbadshare",32,"A open conflicts with an existing open."},
968 {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
969 {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
970 {"ERRFCBUnavail",35,"No FCBs are available to process request."},
971 {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
979 err_code_struct *err_msgs;
982 {0x01,"ERRDOS",dos_msgs},
983 {0x02,"ERRSRV",server_msgs},
984 {0x03,"ERRHRD",hard_msgs},
985 {0x04,"ERRXOS",NULL},
986 {0xE1,"ERRRMX1",NULL},
987 {0xE2,"ERRRMX2",NULL},
988 {0xE3,"ERRRMX3",NULL},
989 {0xFF,"ERRCMD",NULL},
993 /****************************************************************************
994 return a SMB error string from a SMB buffer
995 ****************************************************************************/
996 char *smb_errstr(char *inbuf)
999 int class = CVAL(inbuf,smb_rcls);
1000 int num = SVAL(inbuf,smb_err);
1003 for (i=0;err_classes[i].class;i++)
1004 if (err_classes[i].code == class)
1006 if (err_classes[i].err_msgs)
1008 err_code_struct *err = err_classes[i].err_msgs;
1009 for (j=0;err[j].name;j++)
1010 if (num == err[j].code)
1013 sprintf(ret,"%s - %s (%s)",err_classes[i].class,
1014 err[j].name,err[j].message);
1016 sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
1021 sprintf(ret,"%s - %d",err_classes[i].class,num);
1025 sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);