convert the credentials code back to uchar[8] from uint32[2]
[Samba.git] / source / client / clientutil.c
blob1794615cd0ffdea44e904aabb53b96b9c5a8c270
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB client
5 Copyright (C) Andrew Tridgell 1994-1997
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.
22 #ifdef SYSLOG
23 #undef SYSLOG
24 #endif
26 #include "includes.h"
28 #ifndef REGISTER
29 #define REGISTER 0
30 #endif
32 pstring service="";
33 pstring desthost="";
34 extern pstring myname;
35 pstring password = "";
36 pstring username="";
37 pstring workgroup=WORKGROUP;
38 BOOL got_pass = False;
39 BOOL connect_as_printer = False;
40 BOOL connect_as_ipc = False;
42 char cryptkey[8];
43 BOOL doencrypt=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)
51 int name_type = 0x20;
53 int max_protocol = PROTOCOL_NT1;
55 BOOL readbraw_supported = False;
56 BOOL writebraw_supported = False;
58 extern int DEBUGLEVEL;
60 int cnum = 0;
61 int pid = 0;
62 int gid = 0;
63 int uid = 0;
64 int mid = 0;
66 int max_xmit = BUFFER_SIZE;
68 BOOL have_ip = False;
70 extern struct in_addr dest_ip;
72 extern int Protocol;
74 extern int Client;
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_COREPLUS)
87 SCVAL(outbuf,smb_flg,0x8);
88 SSVAL(outbuf,smb_flg2,0x1);
92 /****************************************************************************
93 call a remote api
94 ****************************************************************************/
95 BOOL cli_call_api(char *pipe_name, int pipe_name_len,
96 int prcnt,int drcnt, int srcnt,
97 int mprcnt,int mdrcnt,
98 int *rprcnt,int *rdrcnt,
99 char *param,char *data, uint16 *setup,
100 char **rparam,char **rdata)
102 static char *inbuf=NULL;
103 static char *outbuf=NULL;
105 if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
106 if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
108 if (pipe_name_len == 0) pipe_name_len = strlen(pipe_name);
110 cli_send_trans_request(outbuf,SMBtrans,pipe_name, pipe_name_len, 0,0,
111 data, param, setup,
112 drcnt, prcnt, srcnt,
113 mdrcnt, mprcnt, 0);
115 return (cli_receive_trans_response(inbuf,SMBtrans,
116 rdrcnt,rprcnt,
117 rdata,rparam));
121 /****************************************************************************
122 receive a SMB trans or trans2 response allocating the necessary memory
123 ****************************************************************************/
124 BOOL cli_receive_trans_response(char *inbuf,int trans,
125 int *data_len,int *param_len,
126 char **data,char **param)
128 int total_data=0;
129 int total_param=0;
130 int this_data,this_param;
132 *data_len = *param_len = 0;
134 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
135 show_msg(inbuf);
137 /* sanity check */
138 if (CVAL(inbuf,smb_com) != trans)
140 DEBUG(0,("Expected %s response, got command 0x%02x\n",
141 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
142 return(False);
144 if (CVAL(inbuf,smb_rcls) != 0)
145 return(False);
147 /* parse out the lengths */
148 total_data = SVAL(inbuf,smb_tdrcnt);
149 total_param = SVAL(inbuf,smb_tprcnt);
151 /* allocate it */
152 *data = Realloc(*data,total_data);
153 *param = Realloc(*param,total_param);
155 while (1)
157 this_data = SVAL(inbuf,smb_drcnt);
158 this_param = SVAL(inbuf,smb_prcnt);
159 if (this_data)
160 memcpy(*data + SVAL(inbuf,smb_drdisp),
161 smb_base(inbuf) + SVAL(inbuf,smb_droff),
162 this_data);
163 if (this_param)
164 memcpy(*param + SVAL(inbuf,smb_prdisp),
165 smb_base(inbuf) + SVAL(inbuf,smb_proff),
166 this_param);
167 *data_len += this_data;
168 *param_len += this_param;
170 /* parse out the total lengths again - they can shrink! */
171 total_data = SVAL(inbuf,smb_tdrcnt);
172 total_param = SVAL(inbuf,smb_tprcnt);
174 if (total_data <= *data_len && total_param <= *param_len)
175 break;
177 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
178 show_msg(inbuf);
180 /* sanity check */
181 if (CVAL(inbuf,smb_com) != trans)
183 DEBUG(0,("Expected %s response, got command 0x%02x\n",
184 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
185 return(False);
187 if (CVAL(inbuf,smb_rcls) != 0)
188 return(False);
191 return(True);
196 /****************************************************************************
197 send a SMB trans or trans2 request
198 ****************************************************************************/
199 BOOL cli_send_trans_request(char *outbuf,int trans,
200 char *name,int namelen, int fid,int flags,
201 char *data,char *param,uint16 *setup,
202 int ldata,int lparam,int lsetup,
203 int mdata,int mparam,int msetup)
205 int i;
206 int this_ldata,this_lparam;
207 int tot_data=0,tot_param=0;
208 char *outdata,*outparam;
209 pstring inbuf;
210 char *p;
212 this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
213 this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
215 bzero(outbuf,smb_size);
216 set_message(outbuf,14+lsetup,0,True);
217 CVAL(outbuf,smb_com) = trans;
218 SSVAL(outbuf,smb_tid,cnum);
219 cli_setup_pkt(outbuf);
221 outparam = smb_buf(outbuf)+(trans==SMBtrans ? namelen+1 : 3);
222 outdata = outparam+this_lparam;
224 /* primary request */
225 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
226 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
227 SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
228 SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
229 SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
230 SSVAL(outbuf,smb_flags,flags); /* flags */
231 SIVAL(outbuf,smb_timeout,0); /* timeout */
232 SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
233 SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
234 SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
235 SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
236 SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
237 for (i=0;i<lsetup;i++) /* setup[] */
238 SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
239 p = smb_buf(outbuf);
240 if (trans==SMBtrans)
241 memcpy(p,name, namelen+1); /* name[] */
242 else
244 *p++ = 0; /* put in a null smb_name */
245 *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
247 if (this_lparam) /* param[] */
248 memcpy(outparam,param,this_lparam);
249 if (this_ldata) /* data[] */
250 memcpy(outdata,data,this_ldata);
251 set_message(outbuf,14+lsetup, /* wcnt, bcc */
252 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
254 show_msg(outbuf);
255 send_smb(Client,outbuf);
257 if (this_ldata < ldata || this_lparam < lparam)
259 /* receive interim response */
260 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
262 DEBUG(0,("%s request failed (%s)\n",
263 trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
264 return(False);
267 tot_data = this_ldata;
268 tot_param = this_lparam;
270 while (tot_data < ldata || tot_param < lparam)
272 this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
273 this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
275 set_message(outbuf,trans==SMBtrans?8:9,0,True);
276 CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
278 outparam = smb_buf(outbuf);
279 outdata = outparam+this_lparam;
281 /* secondary request */
282 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
283 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
284 SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
285 SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
286 SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
287 SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
288 SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
289 SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
290 if (trans==SMBtrans2)
291 SSVAL(outbuf,smb_sfid,fid); /* fid */
292 if (this_lparam) /* param[] */
293 memcpy(outparam,param,this_lparam);
294 if (this_ldata) /* data[] */
295 memcpy(outdata,data,this_ldata);
296 set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
297 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
299 show_msg(outbuf);
300 send_smb(Client,outbuf);
302 tot_data += this_ldata;
303 tot_param += this_lparam;
307 return(True);
311 /****************************************************************************
312 send a session request
313 ****************************************************************************/
314 BOOL cli_send_session_request(char *inbuf,char *outbuf)
316 fstring dest;
317 char *p;
318 int len = 4;
319 /* send a session request (RFC 8002) */
321 strcpy(dest,desthost);
322 p = strchr(dest,'.');
323 if (p) *p = 0;
325 /* put in the destination name */
326 p = outbuf+len;
327 name_mangle(dest,p,name_type); /* 0x20 is the SMB server NetBIOS type. */
328 len += name_len(p);
330 /* and my name */
331 p = outbuf+len;
332 name_mangle(myname,p,0);
333 len += name_len(p);
335 /* setup the packet length */
336 _smb_setlen(outbuf,len);
337 CVAL(outbuf,0) = 0x81;
339 send_smb(Client,outbuf);
340 DEBUG(5,("Sent session request\n"));
342 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
344 if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
346 /* For information, here is the response structure.
347 * We do the byte-twiddling to for portability.
348 struct RetargetResponse{
349 unsigned char type;
350 unsigned char flags;
351 int16 length;
352 int32 ip_addr;
353 int16 port;
356 extern int Client;
357 int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
358 /* SESSION RETARGET */
359 putip((char *)&dest_ip,inbuf+4);
361 close_sockets();
362 Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
363 if (Client == -1)
364 return False;
366 DEBUG(3,("Retargeted\n"));
368 set_socket_options(Client,user_socket_options);
370 /* Try again */
371 return cli_send_session_request(inbuf,outbuf);
372 } /* C. Hoch 9/14/95 End */
375 if (CVAL(inbuf,0) != 0x82)
377 int ecode = CVAL(inbuf,4);
378 DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
379 CVAL(inbuf,0),ecode,myname,desthost));
380 switch (ecode)
382 case 0x80:
383 DEBUG(0,("Not listening on called name\n"));
384 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
385 DEBUG(0,("You may find the -I option useful for this\n"));
386 break;
387 case 0x81:
388 DEBUG(0,("Not listening for calling name\n"));
389 DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
390 DEBUG(0,("You may find the -n option useful for this\n"));
391 break;
392 case 0x82:
393 DEBUG(0,("Called name not present\n"));
394 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
395 DEBUG(0,("You may find the -I option useful for this\n"));
396 break;
397 case 0x83:
398 DEBUG(0,("Called name present, but insufficient resources\n"));
399 DEBUG(0,("Perhaps you should try again later?\n"));
400 break;
401 default:
402 DEBUG(0,("Unspecified error 0x%X\n",ecode));
403 DEBUG(0,("Your server software is being unfriendly\n"));
404 break;
406 return(False);
408 return(True);
411 static struct {
412 int prot;
413 char *name;
414 } prots[] = {
415 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
416 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
417 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
418 {PROTOCOL_LANMAN1,"LANMAN1.0"},
419 {PROTOCOL_LANMAN2,"LM1.2X002"},
420 {PROTOCOL_LANMAN2,"Samba"},
421 {PROTOCOL_NT1,"NT LM 0.12"},
422 {PROTOCOL_NT1,"NT LANMAN 1.0"},
423 {-1,NULL}
427 /****************************************************************************
428 send a login command
429 ****************************************************************************/
430 BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
432 BOOL was_null = (!inbuf && !outbuf);
433 int sesskey=0;
434 time_t servertime = 0;
435 extern int serverzone;
436 int sec_mode=0;
437 int crypt_len;
438 int max_vcs=0;
439 char *pass = NULL;
440 pstring dev;
441 char *p;
442 int numprots;
443 int tries=0;
445 if (was_null)
447 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
448 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
451 #if AJT
452 if (strstr(service,"IPC$")) connect_as_ipc = True;
453 #endif
455 strcpy(dev,"A:");
456 if (connect_as_printer)
457 strcpy(dev,"LPT1:");
458 if (connect_as_ipc)
459 strcpy(dev,"IPC");
462 if (start_session && !cli_send_session_request(inbuf,outbuf))
464 if (was_null)
466 free(inbuf);
467 free(outbuf);
469 return(False);
472 bzero(outbuf,smb_size);
474 /* setup the protocol strings */
476 int plength;
478 for (plength=0,numprots=0;
479 prots[numprots].name && prots[numprots].prot<=max_protocol;
480 numprots++)
481 plength += strlen(prots[numprots].name)+2;
483 set_message(outbuf,0,plength,True);
485 p = smb_buf(outbuf);
486 for (numprots=0;
487 prots[numprots].name && prots[numprots].prot<=max_protocol;
488 numprots++)
490 *p++ = 2;
491 strcpy(p,prots[numprots].name);
492 p += strlen(p) + 1;
496 CVAL(outbuf,smb_com) = SMBnegprot;
497 cli_setup_pkt(outbuf);
499 CVAL(smb_buf(outbuf),0) = 2;
501 send_smb(Client,outbuf);
502 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
504 show_msg(inbuf);
506 if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
508 DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
509 myname,desthost,smb_errstr(inbuf)));
510 if (was_null)
512 free(inbuf);
513 free(outbuf);
515 return(False);
518 Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
521 if (Protocol < PROTOCOL_NT1) {
522 sec_mode = SVAL(inbuf,smb_vwv1);
523 max_xmit = SVAL(inbuf,smb_vwv2);
524 sesskey = IVAL(inbuf,smb_vwv6);
525 serverzone = SVALS(inbuf,smb_vwv10)*60;
526 /* this time is converted to GMT by make_unix_date */
527 servertime = make_unix_date(inbuf+smb_vwv8);
528 if (Protocol >= PROTOCOL_COREPLUS) {
529 readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
530 writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
532 crypt_len = smb_buflen(inbuf);
533 memcpy(cryptkey,smb_buf(inbuf),8);
534 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
535 max_vcs = SVAL(inbuf,smb_vwv4);
536 DEBUG(3,("max vcs %d\n",max_vcs));
537 DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
538 } else {
539 /* NT protocol */
540 sec_mode = CVAL(inbuf,smb_vwv1);
541 max_xmit = IVAL(inbuf,smb_vwv3+1);
542 sesskey = IVAL(inbuf,smb_vwv7+1);
543 serverzone = SVALS(inbuf,smb_vwv15+1)*60;
544 /* this time arrives in real GMT */
545 servertime = interpret_long_date(inbuf+smb_vwv11+1);
546 crypt_len = CVAL(inbuf,smb_vwv16+1);
547 memcpy(cryptkey,smb_buf(inbuf),8);
548 if (IVAL(inbuf,smb_vwv9+1) & 1)
549 readbraw_supported = writebraw_supported = True;
550 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
551 max_vcs = SVAL(inbuf,smb_vwv2+1);
552 DEBUG(3,("max vcs %d\n",max_vcs));
553 DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
554 DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
557 DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
558 DEBUG(3,("max xmt %d\n",max_xmit));
559 DEBUG(3,("Got %d byte crypt key\n",crypt_len));
560 DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
562 doencrypt = ((sec_mode & 2) != 0);
564 if (servertime) {
565 static BOOL done_time = False;
566 if (!done_time) {
567 DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
568 asctime(LocalTime(&servertime)),
569 -(double)(serverzone/3600.0)));
570 done_time = True;
574 get_pass:
576 if (got_pass)
577 pass = password;
578 else
579 pass = (char *)getpass("Password: ");
581 /* use a blank username for the 2nd try with a blank password */
582 if (tries++ && !*pass)
583 *username = 0;
585 if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
587 fstring pword;
588 int passlen = strlen(pass)+1;
589 strcpy(pword,pass);
591 if (doencrypt && *pass) {
592 DEBUG(3,("Using encrypted passwords\n"));
593 passlen = 24;
594 SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
597 /* if in share level security then don't send a password now */
598 if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;}
600 /* send a session setup command */
601 bzero(outbuf,smb_size);
603 if (Protocol < PROTOCOL_NT1) {
604 set_message(outbuf,10,1 + strlen(username) + passlen,True);
605 CVAL(outbuf,smb_com) = SMBsesssetupX;
606 cli_setup_pkt(outbuf);
608 CVAL(outbuf,smb_vwv0) = 0xFF;
609 SSVAL(outbuf,smb_vwv2,max_xmit);
610 SSVAL(outbuf,smb_vwv3,2);
611 SSVAL(outbuf,smb_vwv4,max_vcs-1);
612 SIVAL(outbuf,smb_vwv5,sesskey);
613 SSVAL(outbuf,smb_vwv7,passlen);
614 p = smb_buf(outbuf);
615 memcpy(p,pword,passlen);
616 p += passlen;
617 strcpy(p,username);
618 } else {
619 if (!doencrypt) passlen--;
620 /* for Win95 */
621 set_message(outbuf,13,0,True);
622 CVAL(outbuf,smb_com) = SMBsesssetupX;
623 cli_setup_pkt(outbuf);
625 CVAL(outbuf,smb_vwv0) = 0xFF;
626 SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
627 SSVAL(outbuf,smb_vwv3,2);
628 SSVAL(outbuf,smb_vwv4,getpid());
629 SIVAL(outbuf,smb_vwv5,sesskey);
630 SSVAL(outbuf,smb_vwv7,passlen);
631 SSVAL(outbuf,smb_vwv8,0);
632 p = smb_buf(outbuf);
633 memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
634 strcpy(p,username);p = skip_string(p,1);
635 strcpy(p,workgroup);p = skip_string(p,1);
636 strcpy(p,"Unix");p = skip_string(p,1);
637 strcpy(p,"Samba");p = skip_string(p,1);
638 set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
641 send_smb(Client,outbuf);
642 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
644 show_msg(inbuf);
646 if (CVAL(inbuf,smb_rcls) != 0)
648 if (! *pass &&
649 ((CVAL(inbuf,smb_rcls) == ERRDOS &&
650 SVAL(inbuf,smb_err) == ERRnoaccess) ||
651 (CVAL(inbuf,smb_rcls) == ERRSRV &&
652 SVAL(inbuf,smb_err) == ERRbadpw)))
654 got_pass = False;
655 DEBUG(3,("resending login\n"));
656 goto get_pass;
659 DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
660 username,myname,desthost,smb_errstr(inbuf)));
661 DEBUG(0,("You might find the -U, -W or -n options useful\n"));
662 DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
663 DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
664 if (was_null)
666 free(inbuf);
667 free(outbuf);
669 return(False);
672 if (Protocol >= PROTOCOL_NT1) {
673 char *domain,*os,*lanman;
674 p = smb_buf(inbuf);
675 os = p;
676 lanman = skip_string(os,1);
677 domain = skip_string(lanman,1);
678 if (*domain || *os || *lanman)
679 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
682 /* use the returned uid from now on */
683 if (SVAL(inbuf,smb_uid) != uid)
684 DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
685 SVAL(inbuf,smb_uid),uid));
686 uid = SVAL(inbuf,smb_uid);
689 if (sec_mode & 1) {
690 if (SVAL(inbuf, smb_vwv2) & 1)
691 DEBUG(1,("connected as guest "));
692 DEBUG(1,("security=user\n"));
693 } else {
694 DEBUG(1,("security=share\n"));
697 /* now we've got a connection - send a tcon message */
698 bzero(outbuf,smb_size);
700 if (strncmp(service,"\\\\",2) != 0)
702 DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
703 DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
707 again2:
710 int passlen = strlen(pass)+1;
711 fstring pword;
712 strcpy(pword,pass);
714 if (doencrypt && *pass) {
715 passlen=24;
716 SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
719 /* if in user level security then don't send a password now */
720 if ((sec_mode & 1)) {
721 strcpy(pword, ""); passlen=1;
724 if (Protocol <= PROTOCOL_COREPLUS) {
725 set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True);
726 CVAL(outbuf,smb_com) = SMBtcon;
727 cli_setup_pkt(outbuf);
729 p = smb_buf(outbuf);
730 *p++ = 0x04;
731 strcpy(p, service);
732 p = skip_string(p,1);
733 *p++ = 0x04;
734 memcpy(p,pword,passlen);
735 p += passlen;
736 *p++ = 0x04;
737 strcpy(p, dev);
739 else {
740 set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
741 CVAL(outbuf,smb_com) = SMBtconX;
742 cli_setup_pkt(outbuf);
744 SSVAL(outbuf,smb_vwv0,0xFF);
745 SSVAL(outbuf,smb_vwv3,passlen);
747 p = smb_buf(outbuf);
748 memcpy(p,pword,passlen);
749 p += passlen;
750 strcpy(p,service);
751 p = skip_string(p,1);
752 strcpy(p,dev);
756 send_smb(Client,outbuf);
757 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
759 /* trying again with a blank password */
760 if (CVAL(inbuf,smb_rcls) != 0 &&
761 (int)strlen(pass) > 0 &&
762 !doencrypt &&
763 Protocol >= PROTOCOL_LANMAN1)
765 DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
766 strcpy(pass,"");
767 goto again2;
770 if (CVAL(inbuf,smb_rcls) != 0)
772 DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
773 DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
774 DEBUG(0,("Some servers insist that these be in uppercase\n"));
775 if (was_null)
777 free(inbuf);
778 free(outbuf);
780 return(False);
784 if (Protocol <= PROTOCOL_COREPLUS) {
785 max_xmit = SVAL(inbuf,smb_vwv0);
787 cnum = SVAL(inbuf,smb_vwv1);
789 else {
790 max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
791 if (max_xmit <= 0)
792 max_xmit = BUFFER_SIZE - 4;
794 cnum = SVAL(inbuf,smb_tid);
797 DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
799 if (was_null)
801 free(inbuf);
802 free(outbuf);
805 return True;
809 /****************************************************************************
810 send a logout command
811 ****************************************************************************/
812 void cli_send_logout(void )
814 pstring inbuf,outbuf;
816 DEBUG(5,("cli_send_logout\n"));
818 bzero(outbuf,smb_size);
819 set_message(outbuf,0,0,True);
820 CVAL(outbuf,smb_com) = SMBtdis;
821 SSVAL(outbuf,smb_tid,cnum);
822 cli_setup_pkt(outbuf);
824 send_smb(Client,outbuf);
825 receive_smb(Client,inbuf,SHORT_TIMEOUT);
827 if (CVAL(inbuf,smb_rcls) != 0)
829 DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
833 #ifdef STATS
834 stats_report();
835 #endif
836 exit(0);
840 /****************************************************************************
841 open the client sockets
842 ****************************************************************************/
843 BOOL cli_open_sockets(int port )
845 static int last_port;
846 char *host;
847 pstring service2;
848 extern int Client;
849 BOOL failed = True;
851 if (port == 0) port=last_port;
852 last_port=port;
854 strupper(service);
856 if (*desthost)
858 host = desthost;
860 else
862 strcpy(service2,service);
863 host = strtok(service2,"\\/");
864 if (!host) {
865 DEBUG(0,("Badly formed host name\n"));
866 return(False);
868 strcpy(desthost,host);
871 if (!(*myname)) {
872 get_myname(myname,NULL);
874 strupper(myname);
876 DEBUG(3,("Opening sockets\n"));
878 if (!have_ip)
880 struct hostent *hp;
882 if ((hp = Get_Hostbyname(host)))
884 putip((char *)&dest_ip,(char *)hp->h_addr);
885 failed = False;
887 else
889 #ifdef USENMB
890 /* Try and resolve the name with the netbios server */
891 int bcast;
893 if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3,
894 interpret_addr(lp_socket_address()))) != -1) {
895 set_socket_options(bcast, "SO_BROADCAST");
897 if (name_query(bcast, host, name_type, True, True, *iface_bcast(dest_ip),
898 &dest_ip,0)) {
899 failed = False;
901 close (bcast);
903 #endif
904 if (failed) {
905 DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
906 return False;
911 Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
912 if (Client == -1)
913 return False;
915 DEBUG(3,("Connected\n"));
917 set_socket_options(Client,user_socket_options);
919 return True;
922 /****************************************************************************
923 close and open the connection again
924 ****************************************************************************/
925 BOOL cli_reopen_connection(char *inbuf,char *outbuf)
927 static int open_count=0;
929 open_count++;
931 if (open_count>5) return(False);
933 DEBUG(1,("Trying to re-open connection\n"));
935 set_message(outbuf,0,0,True);
936 SCVAL(outbuf,smb_com,SMBtdis);
937 SSVAL(outbuf,smb_tid,cnum);
938 cli_setup_pkt(outbuf);
940 send_smb(Client,outbuf);
941 receive_smb(Client,inbuf,SHORT_TIMEOUT);
943 close_sockets();
944 if (!cli_open_sockets(0)) return(False);
946 return(cli_send_login(inbuf,outbuf,True,True));