sync with SAMBA_2_2
[Samba/gbeck.git] / source / libsmb / cliconnect.c
blob06f283c321a57510b8a2d77acf4f996119aaa785
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 client connect/disconnect routines
5 Copyright (C) Andrew Tridgell 1994-1998
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 #define NO_SYSLOG
24 #include "includes.h"
27 static struct {
28 int prot;
29 char *name;
31 prots[] =
33 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
34 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
35 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
36 {PROTOCOL_LANMAN1,"LANMAN1.0"},
37 {PROTOCOL_LANMAN2,"LM1.2X002"},
38 {PROTOCOL_LANMAN2,"Samba"},
39 {PROTOCOL_NT1,"NT LANMAN 1.0"},
40 {PROTOCOL_NT1,"NT LM 0.12"},
41 {-1,NULL}
45 /****************************************************************************
46 Send a session setup. The username and workgroup is in UNIX character
47 format and must be converted to DOS codepage format before sending. If the
48 password is in plaintext, the same should be done.
49 ****************************************************************************/
51 BOOL cli_session_setup(struct cli_state *cli,
52 char *user,
53 char *pass, int passlen,
54 char *ntpass, int ntpasslen,
55 char *workgroup)
57 char *p;
58 fstring pword, ntpword;
59 fstring user2;
61 /* allow for workgroups as part of the username */
62 fstrcpy(user2, user);
63 if ((p=strchr(user2,'\\')) || (p=strchr(user2,'/'))) {
64 *p = 0;
65 user = p+1;
66 workgroup = user2;
69 if (cli->protocol < PROTOCOL_LANMAN1)
70 return True;
72 if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
73 return False;
76 if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) {
77 /* Null session connect. */
78 pword[0] = '\0';
79 ntpword[0] = '\0';
80 } else {
81 if ((cli->sec_mode & 2) && passlen != 24) {
83 * Encrypted mode needed, and non encrypted password supplied.
85 passlen = 24;
86 ntpasslen = 24;
87 fstrcpy(pword, pass);
88 unix_to_dos(pword,True);
89 fstrcpy(ntpword, ntpass);;
90 SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword);
91 SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword);
92 } else if ((cli->sec_mode & 2) && passlen == 24) {
94 * Encrypted mode needed, and encrypted password supplied.
96 memcpy(pword, pass, passlen);
97 if(ntpasslen == 24) {
98 memcpy(ntpword, ntpass, ntpasslen);
99 } else {
100 fstrcpy(ntpword, "");
101 ntpasslen = 0;
103 } else {
105 * Plaintext mode needed, assume plaintext supplied.
107 passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
108 fstrcpy(ntpword, "");
109 ntpasslen = 0;
113 /* if in share level security then don't send a password now */
114 if (!(cli->sec_mode & 1)) {
115 fstrcpy(pword, "");
116 passlen=1;
117 fstrcpy(ntpword, "");
118 ntpasslen=1;
121 /* send a session setup command */
122 memset(cli->outbuf,'\0',smb_size);
124 if (cli->protocol < PROTOCOL_NT1)
126 set_message(cli->outbuf,10, 0, True);
127 CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
128 cli_setup_packet(cli);
130 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
131 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
132 SSVAL(cli->outbuf,smb_vwv3,2);
133 SSVAL(cli->outbuf,smb_vwv4,1);
134 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
135 SSVAL(cli->outbuf,smb_vwv7,passlen);
136 p = smb_buf(cli->outbuf);
137 memcpy(p,pword,passlen);
138 p += passlen;
139 p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_UPPER|STR_TERMINATE);
140 cli_setup_bcc(cli, p);
142 else
144 uint32 capabilities;
146 capabilities = CAP_NT_SMBS;
147 if (cli->use_level_II_oplocks) {
148 capabilities |= CAP_LEVEL_II_OPLOCKS;
150 if (cli->capabilities & CAP_UNICODE) {
151 capabilities |= CAP_UNICODE;
153 set_message(cli->outbuf,13,0,True);
154 CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
155 cli_setup_packet(cli);
157 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
158 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
159 SSVAL(cli->outbuf,smb_vwv3,2);
160 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
161 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
162 SSVAL(cli->outbuf,smb_vwv7,passlen);
163 SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
164 SIVAL(cli->outbuf,smb_vwv11,capabilities);
165 p = smb_buf(cli->outbuf);
166 memcpy(p,pword,passlen);
167 p += SVAL(cli->outbuf,smb_vwv7);
168 memcpy(p,ntpword,ntpasslen);
169 p += SVAL(cli->outbuf,smb_vwv8);
170 p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER);
171 p += clistr_push(cli, p, workgroup, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER);
172 p += clistr_push(cli, p, "Unix", -1, STR_CONVERT|STR_TERMINATE);
173 p += clistr_push(cli, p, "Samba", -1, STR_CONVERT|STR_TERMINATE);
174 cli_setup_bcc(cli, p);
177 cli_send_smb(cli);
178 if (!cli_receive_smb(cli))
179 return False;
181 show_msg(cli->inbuf);
183 if (CVAL(cli->inbuf,smb_rcls) != 0) {
184 return False;
187 /* use the returned vuid from now on */
188 cli->vuid = SVAL(cli->inbuf,smb_uid);
190 if (cli->protocol >= PROTOCOL_NT1) {
192 * Save off some of the connected server
193 * info.
195 char *q = smb_buf(cli->inbuf);
196 q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT);
197 q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT);
198 q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT);
201 fstrcpy(cli->user_name, user);
203 return True;
206 /****************************************************************************
207 Send a uloggoff.
208 *****************************************************************************/
210 BOOL cli_ulogoff(struct cli_state *cli)
212 memset(cli->outbuf,'\0',smb_size);
213 set_message(cli->outbuf,2,0,True);
214 CVAL(cli->outbuf,smb_com) = SMBulogoffX;
215 cli_setup_packet(cli);
216 SSVAL(cli->outbuf,smb_vwv0,0xFF);
217 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
219 cli_send_smb(cli);
220 if (!cli_receive_smb(cli))
221 return False;
223 return CVAL(cli->inbuf,smb_rcls) == 0;
226 /****************************************************************************
227 send a tconX
228 ****************************************************************************/
229 BOOL cli_send_tconX(struct cli_state *cli,
230 char *share, char *dev, char *pass, int passlen)
232 fstring fullshare, pword, dos_pword;
233 char *p;
234 memset(cli->outbuf,'\0',smb_size);
235 memset(cli->inbuf,'\0',smb_size);
237 fstrcpy(cli->share, share);
239 /* in user level security don't send a password now */
240 if (cli->sec_mode & 1) {
241 passlen = 1;
242 pass = "";
245 if ((cli->sec_mode & 2) && *pass && passlen != 24) {
247 * Non-encrypted passwords - convert to DOS codepage before encryption.
249 passlen = 24;
250 fstrcpy(dos_pword,pass);
251 unix_to_dos(dos_pword,True);
252 SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword);
253 } else {
254 if((cli->sec_mode & 3) == 0) {
256 * Non-encrypted passwords - convert to DOS codepage before using.
258 passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
259 } else {
260 memcpy(pword, pass, passlen);
264 slprintf(fullshare, sizeof(fullshare)-1,
265 "\\\\%s\\%s", cli->desthost, share);
266 unix_to_dos(fullshare, True);
267 strupper(fullshare);
269 set_message(cli->outbuf,4, 0, True);
270 CVAL(cli->outbuf,smb_com) = SMBtconX;
271 cli_setup_packet(cli);
273 SSVAL(cli->outbuf,smb_vwv0,0xFF);
274 SSVAL(cli->outbuf,smb_vwv3,passlen);
276 p = smb_buf(cli->outbuf);
277 memcpy(p,pword,passlen);
278 p += passlen;
279 p += clistr_push(cli, p, fullshare, -1, STR_CONVERT | STR_TERMINATE);
280 fstrcpy(p, dev); p += strlen(dev)+1;
282 cli_setup_bcc(cli, p);
284 SCVAL(cli->inbuf,smb_rcls, 1);
286 cli_send_smb(cli);
287 if (!cli_receive_smb(cli))
288 return False;
290 if (CVAL(cli->inbuf,smb_rcls) != 0) {
291 return False;
294 fstrcpy(cli->dev, "A:");
296 if (cli->protocol >= PROTOCOL_NT1) {
297 clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE | STR_CONVERT);
300 if (strcasecmp(share,"IPC$")==0) {
301 fstrcpy(cli->dev, "IPC");
304 /* only grab the device if we have a recent protocol level */
305 if (cli->protocol >= PROTOCOL_NT1 &&
306 smb_buflen(cli->inbuf) == 3) {
307 /* almost certainly win95 - enable bug fixes */
308 cli->win95 = True;
311 cli->cnum = SVAL(cli->inbuf,smb_tid);
312 return True;
316 /****************************************************************************
317 send a tree disconnect
318 ****************************************************************************/
319 BOOL cli_tdis(struct cli_state *cli)
321 memset(cli->outbuf,'\0',smb_size);
322 set_message(cli->outbuf,0,0,True);
323 CVAL(cli->outbuf,smb_com) = SMBtdis;
324 SSVAL(cli->outbuf,smb_tid,cli->cnum);
325 cli_setup_packet(cli);
327 cli_send_smb(cli);
328 if (!cli_receive_smb(cli))
329 return False;
331 return CVAL(cli->inbuf,smb_rcls) == 0;
335 /****************************************************************************
336 send a negprot command
337 ****************************************************************************/
338 void cli_negprot_send(struct cli_state *cli)
340 char *p;
341 int numprots;
343 memset(cli->outbuf,'\0',smb_size);
345 /* setup the protocol strings */
346 set_message(cli->outbuf,0,0,True);
348 p = smb_buf(cli->outbuf);
349 for (numprots=0;
350 prots[numprots].name && prots[numprots].prot<=cli->protocol;
351 numprots++) {
352 *p++ = 2;
353 pstrcpy(p,prots[numprots].name);
354 unix_to_dos(p,True);
355 p += strlen(p) + 1;
358 CVAL(cli->outbuf,smb_com) = SMBnegprot;
359 cli_setup_bcc(cli, p);
360 cli_setup_packet(cli);
362 CVAL(smb_buf(cli->outbuf),0) = 2;
364 cli_send_smb(cli);
368 /****************************************************************************
369 send a negprot command
370 ****************************************************************************/
371 BOOL cli_negprot(struct cli_state *cli)
373 char *p;
374 int numprots;
375 int plength;
377 memset(cli->outbuf,'\0',smb_size);
379 /* setup the protocol strings */
380 for (plength=0,numprots=0;
381 prots[numprots].name && prots[numprots].prot<=cli->protocol;
382 numprots++)
383 plength += strlen(prots[numprots].name)+2;
385 set_message(cli->outbuf,0,plength,True);
387 p = smb_buf(cli->outbuf);
388 for (numprots=0;
389 prots[numprots].name && prots[numprots].prot<=cli->protocol;
390 numprots++) {
391 *p++ = 2;
392 pstrcpy(p,prots[numprots].name);
393 unix_to_dos(p,True);
394 p += strlen(p) + 1;
397 CVAL(cli->outbuf,smb_com) = SMBnegprot;
398 cli_setup_packet(cli);
400 CVAL(smb_buf(cli->outbuf),0) = 2;
402 cli_send_smb(cli);
403 if (!cli_receive_smb(cli))
404 return False;
406 show_msg(cli->inbuf);
408 if (CVAL(cli->inbuf,smb_rcls) != 0 ||
409 ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
410 return(False);
413 cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
416 if (cli->protocol >= PROTOCOL_NT1) {
417 /* NT protocol */
418 cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
419 cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
420 cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
421 cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
422 cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
423 cli->serverzone *= 60;
424 /* this time arrives in real GMT */
425 cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
426 memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
427 cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
428 if (cli->capabilities & CAP_RAW_MODE) {
429 cli->readbraw_supported = True;
430 cli->writebraw_supported = True;
432 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
433 cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
434 cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
435 cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
436 cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
437 cli->serverzone *= 60;
438 /* this time is converted to GMT by make_unix_date */
439 cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
440 cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
441 cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
442 memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
443 } else {
444 /* the old core protocol */
445 cli->sec_mode = 0;
446 cli->serverzone = TimeDiff(time(NULL));
449 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
451 /* a way to force ascii SMB */
452 if (getenv("CLI_FORCE_ASCII")) {
453 cli->capabilities &= ~CAP_UNICODE;
456 return True;
460 /****************************************************************************
461 send a session request. see rfc1002.txt 4.3 and 4.3.2
462 ****************************************************************************/
463 BOOL cli_session_request(struct cli_state *cli,
464 struct nmb_name *calling, struct nmb_name *called)
466 char *p;
467 int len = 4;
468 extern pstring user_socket_options;
470 /* send a session request (RFC 1002) */
472 memcpy(&(cli->calling), calling, sizeof(*calling));
473 memcpy(&(cli->called ), called , sizeof(*called ));
475 /* put in the destination name */
476 p = cli->outbuf+len;
477 name_mangle(cli->called .name, p, cli->called .name_type);
478 len += name_len(p);
480 /* and my name */
481 p = cli->outbuf+len;
482 name_mangle(cli->calling.name, p, cli->calling.name_type);
483 len += name_len(p);
485 /* setup the packet length */
486 _smb_setlen(cli->outbuf,len);
487 CVAL(cli->outbuf,0) = 0x81;
489 #ifdef WITH_SSL
490 retry:
491 #endif /* WITH_SSL */
493 cli_send_smb(cli);
494 DEBUG(5,("Sent session request\n"));
496 if (!cli_receive_smb(cli))
497 return False;
499 if (CVAL(cli->inbuf,0) == 0x84) {
500 /* C. Hoch 9/14/95 Start */
501 /* For information, here is the response structure.
502 * We do the byte-twiddling to for portability.
503 struct RetargetResponse{
504 unsigned char type;
505 unsigned char flags;
506 int16 length;
507 int32 ip_addr;
508 int16 port;
511 int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
512 /* SESSION RETARGET */
513 putip((char *)&cli->dest_ip,cli->inbuf+4);
515 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
516 if (cli->fd == -1)
517 return False;
519 DEBUG(3,("Retargeted\n"));
521 set_socket_options(cli->fd,user_socket_options);
523 /* Try again */
525 static int depth;
526 BOOL ret;
527 if (depth > 4) {
528 DEBUG(0,("Retarget recursion - failing\n"));
529 return False;
531 depth++;
532 ret = cli_session_request(cli, calling, called);
533 depth--;
534 return ret;
536 } /* C. Hoch 9/14/95 End */
538 #ifdef WITH_SSL
539 if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
540 if (!sslutil_fd_is_ssl(cli->fd)){
541 if (sslutil_connect(cli->fd) == 0)
542 goto retry;
545 #endif /* WITH_SSL */
547 if (CVAL(cli->inbuf,0) != 0x82) {
548 /* This is the wrong place to put the error... JRA. */
549 cli->rap_error = CVAL(cli->inbuf,4);
550 return False;
552 return(True);
556 /****************************************************************************
557 open the client sockets
558 ****************************************************************************/
559 BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
561 extern struct in_addr ipzero;
562 extern pstring user_socket_options;
564 fstrcpy(cli->desthost, host);
566 if (!ip || ip_equal(*ip, ipzero)) {
567 if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) {
568 return False;
570 if (ip) *ip = cli->dest_ip;
571 } else {
572 cli->dest_ip = *ip;
575 if (cli->port == 0) cli->port = 139; /* Set to default */
577 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
578 cli->port, cli->timeout);
579 if (cli->fd == -1)
580 return False;
582 set_socket_options(cli->fd,user_socket_options);
584 return True;
587 /****************************************************************************
588 re-establishes a connection
589 ****************************************************************************/
590 BOOL cli_reestablish_connection(struct cli_state *cli)
592 struct nmb_name calling;
593 struct nmb_name called;
594 fstring dest_host;
595 fstring share;
596 fstring dev;
597 BOOL do_tcon = False;
598 int oldfd = cli->fd;
600 if (!cli->initialised || cli->fd == -1)
602 DEBUG(3,("cli_reestablish_connection: not connected\n"));
603 return False;
606 /* copy the parameters necessary to re-establish the connection */
608 if (cli->cnum != 0)
610 fstrcpy(share, cli->share);
611 fstrcpy(dev , cli->dev);
612 do_tcon = True;
615 memcpy(&called , &(cli->called ), sizeof(called ));
616 memcpy(&calling, &(cli->calling), sizeof(calling));
617 fstrcpy(dest_host, cli->full_dest_host_name);
619 DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
620 nmb_namestr(&calling), nmb_namestr(&called),
621 inet_ntoa(cli->dest_ip),
622 cli->user_name, cli->domain));
624 cli->fd = -1;
626 if (cli_establish_connection(cli,
627 dest_host, &cli->dest_ip,
628 &calling, &called,
629 share, dev, False, do_tcon)) {
630 if ((cli->fd != oldfd) && (oldfd != -1)) {
631 close( oldfd );
633 return True;
635 return False;
638 /****************************************************************************
639 establishes a connection right up to doing tconX, reading in a password.
640 ****************************************************************************/
641 BOOL cli_establish_connection(struct cli_state *cli,
642 char *dest_host, struct in_addr *dest_ip,
643 struct nmb_name *calling, struct nmb_name *called,
644 char *service, char *service_type,
645 BOOL do_shutdown, BOOL do_tcon)
647 DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
648 nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip),
649 cli->user_name, cli->domain));
651 /* establish connection */
653 if ((!cli->initialised))
655 return False;
658 if (cli->fd == -1)
660 if (!cli_connect(cli, dest_host, dest_ip))
662 DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
663 nmb_namestr(calling), inet_ntoa(*dest_ip)));
664 return False;
668 if (!cli_session_request(cli, calling, called))
670 DEBUG(1,("failed session request\n"));
671 if (do_shutdown)
672 cli_shutdown(cli);
673 return False;
676 if (!cli_negprot(cli))
678 DEBUG(1,("failed negprot\n"));
679 if (do_shutdown)
680 cli_shutdown(cli);
681 return False;
684 if (cli->pwd.cleartext || cli->pwd.null_pwd)
686 fstring passwd;
687 int pass_len;
689 if (cli->pwd.null_pwd)
691 /* attempt null session */
692 passwd[0] = 0;
693 pass_len = 1;
695 else
697 /* attempt clear-text session */
698 pwd_get_cleartext(&(cli->pwd), passwd);
699 pass_len = strlen(passwd);
702 /* attempt clear-text session */
703 if (!cli_session_setup(cli, cli->user_name,
704 passwd, pass_len,
705 NULL, 0,
706 cli->domain))
708 DEBUG(1,("failed session setup\n"));
709 if (do_shutdown)
711 cli_shutdown(cli);
713 return False;
715 if (do_tcon)
717 if (!cli_send_tconX(cli, service, service_type,
718 (char*)passwd, strlen(passwd)))
720 DEBUG(1,("failed tcon_X\n"));
721 if (do_shutdown)
723 cli_shutdown(cli);
725 return False;
729 else
731 /* attempt encrypted session */
732 unsigned char nt_sess_pwd[24];
733 unsigned char lm_sess_pwd[24];
735 /* creates (storing a copy of) and then obtains a 24 byte password OWF */
736 pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
737 pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
739 /* attempt encrypted session */
740 if (!cli_session_setup(cli, cli->user_name,
741 (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
742 (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
743 cli->domain))
745 DEBUG(1,("failed session setup\n"));
746 if (do_shutdown)
747 cli_shutdown(cli);
748 return False;
751 DEBUG(1,("session setup ok\n"));
753 if (*cli->server_domain || *cli->server_os || *cli->server_type)
755 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
756 cli->server_domain,
757 cli->server_os,
758 cli->server_type));
761 if (do_tcon)
763 if (!cli_send_tconX(cli, service, service_type,
764 (char*)nt_sess_pwd, sizeof(nt_sess_pwd)))
766 DEBUG(1,("failed tcon_X\n"));
767 if (do_shutdown)
768 cli_shutdown(cli);
769 return False;
774 if (do_shutdown)
775 cli_shutdown(cli);
777 return True;
781 /****************************************************************************
782 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
783 ****************************************************************************/
785 BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
786 struct in_addr *pdest_ip)
788 struct nmb_name calling, called;
790 make_nmb_name(&calling, srchost, 0x0);
793 * If the called name is an IP address
794 * then use *SMBSERVER immediately.
797 if(is_ipaddress(desthost))
798 make_nmb_name(&called, "*SMBSERVER", 0x20);
799 else
800 make_nmb_name(&called, desthost, 0x20);
802 if (!cli_session_request(cli, &calling, &called)) {
803 struct nmb_name smbservername;
805 make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
808 * If the name wasn't *SMBSERVER then
809 * try with *SMBSERVER if the first name fails.
812 if (nmb_name_equal(&called, &smbservername)) {
815 * The name used was *SMBSERVER, don't bother with another name.
818 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
819 with error %s.\n", desthost, cli_errstr(cli) ));
820 cli_shutdown(cli);
821 return False;
824 cli_shutdown(cli);
826 if (!cli_initialise(cli) ||
827 !cli_connect(cli, desthost, pdest_ip) ||
828 !cli_session_request(cli, &calling, &smbservername)) {
829 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
830 name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) ));
831 cli_shutdown(cli);
832 return False;
836 return True;