This source file includes following definitions.
- cli_set_port
- cli_receive_smb
- cli_send_smb
- cli_smb_errstr
- cli_errstr
- cli_setup_packet
- fix_char_ptr
- cli_send_trans
- cli_receive_trans
- cli_api_pipe
- cli_api
- cli_NetWkstaUserLogon
- cli_RNetShareEnum
- cli_NetServerEnum
- cli_session_setup
- cli_ulogoff
- cli_send_tconX
- cli_tdis
- cli_rename
- cli_unlink
- cli_mkdir
- cli_rmdir
- cli_nt_create
- cli_open
- cli_close
- cli_lock
- cli_unlock
- cli_issue_read
- cli_read
- cli_issue_write
- cli_write
- cli_smbwrite
- cli_getattrE
- cli_getatr
- cli_setatr
- cli_qpathinfo
- cli_qpathinfo2
- cli_qfileinfo
- interpret_long_filename
- cli_list
- cli_negprot
- cli_session_request
- cli_connect
- cli_initialise
- cli_shutdown
- cli_error
- cli_sockopt
- cli_setpid
- cli_reestablish_connection
- cli_establish_connection
- cli_chkpath
- cli_message_start
- cli_message_text
- cli_message_end
- cli_dskattr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #define NO_SYSLOG
28
29 #include "includes.h"
30 #include "trans2.h"
31
32
33 extern int DEBUGLEVEL;
34 extern pstring user_socket_options;
35
36
37
38
39 int
40 cli_set_port (struct cli_state *cli, int port)
41 {
42 if (port > 0)
43 cli->port = port;
44
45 return cli->port;
46 }
47
48
49
50
51 static BOOL
52 cli_receive_smb (struct cli_state *cli)
53 {
54 return client_receive_smb (cli->fd, cli->inbuf, cli->timeout);
55 }
56
57
58
59
60 static BOOL
61 cli_send_smb (struct cli_state *cli)
62 {
63 size_t len;
64 size_t nwritten = 0;
65 ssize_t ret;
66 BOOL reestablished = False;
67
68 len = smb_len (cli->outbuf) + 4;
69
70 while (nwritten < len)
71 {
72 ret = write_socket (cli->fd, cli->outbuf + nwritten, len - nwritten);
73 if (ret <= 0 && errno == EPIPE && !reestablished)
74 {
75 if (cli_reestablish_connection (cli))
76 {
77 reestablished = True;
78 nwritten = 0;
79 continue;
80 }
81 }
82 if (ret <= 0)
83 {
84 DEBUG (0, ("Error writing %d bytes to client. %d. Exiting\n", (int) len, (int) ret));
85 close_sockets ();
86 exit (1);
87 }
88 nwritten += ret;
89 }
90
91 return True;
92 }
93
94
95
96
97
98 struct
99 {
100 int err;
101 const char *message;
102 } const rap_errmap[] = {
103 {5, "User has insufficient privilege"},
104 {86, "The specified password is invalid"},
105 {2226, "Operation only permitted on a Primary Domain Controller"},
106 {2242, "The password of this user has expired."},
107 {2243, "The password of this user cannot change."},
108 {2244, "This password cannot be used now (password history conflict)."},
109 {2245, "The password is shorter than required."},
110 {2246, "The password of this user is too recent to change."},
111 {0, NULL}
112 };
113
114
115
116
117 static char *
118 cli_smb_errstr (struct cli_state *cli)
119 {
120 return smb_errstr (cli->inbuf);
121 }
122
123
124
125
126
127
128 char *
129 cli_errstr (struct cli_state *cli)
130 {
131 static fstring error_message;
132 uint8 errclass;
133 uint32 errnum;
134 uint32 nt_rpc_error;
135 int i;
136
137
138
139
140
141
142
143
144 cli_error (cli, &errclass, &errnum, &nt_rpc_error);
145
146 if (errclass != 0)
147 {
148 return cli_smb_errstr (cli);
149 }
150
151
152
153
154
155 if (nt_rpc_error)
156 {
157 const char *nt_msg = get_nt_error_msg (nt_rpc_error);
158
159 if (nt_msg == NULL)
160 {
161 slprintf (error_message, sizeof (fstring) - 1, "NT code %d", nt_rpc_error);
162 }
163 else
164 {
165 fstrcpy (error_message, nt_msg);
166 }
167
168 return error_message;
169 }
170
171
172
173
174
175 slprintf (error_message, sizeof (error_message) - 1, "code %d", cli->rap_error);
176
177 for (i = 0; rap_errmap[i].message != NULL; i++)
178 {
179 if (rap_errmap[i].err == cli->rap_error)
180 {
181 fstrcpy (error_message, rap_errmap[i].message);
182 break;
183 }
184 }
185
186 return error_message;
187 }
188
189
190
191
192 static void
193 cli_setup_packet (struct cli_state *cli)
194 {
195 cli->rap_error = 0;
196 cli->nt_error = 0;
197 SSVAL (cli->outbuf, smb_pid, cli->pid);
198 SSVAL (cli->outbuf, smb_uid, cli->vuid);
199 SSVAL (cli->outbuf, smb_mid, cli->mid);
200 if (cli->protocol > PROTOCOL_CORE)
201 {
202 SCVAL (cli->outbuf, smb_flg, 0x8);
203 SSVAL (cli->outbuf, smb_flg2, 0x1);
204 }
205 }
206
207 #if 0
208
209
210
211
212
213 static char *
214 fix_char_ptr (unsigned int datap, unsigned int converter, char *rdata, int rdrcnt)
215 {
216 if (datap == 0)
217 {
218 return "";
219 }
220 else
221 {
222 unsigned int offset = datap - converter;
223
224 if (offset >= rdrcnt)
225 {
226 DEBUG (1, ("bad char ptr: datap=%u, converter=%u rdrcnt=%d>",
227 datap, converter, rdrcnt));
228 return "<ERROR>";
229 }
230 else
231 {
232 return &rdata[offset];
233 }
234 }
235 }
236 #endif
237
238
239
240 static BOOL
241 cli_send_trans (struct cli_state *cli, int trans,
242 const char *name, int pipe_name_len,
243 int fid, int flags,
244 uint16 * setup, int lsetup, int msetup,
245 char *param, int lparam, int mparam, char *data, int ldata, int mdata)
246 {
247 int i;
248 int this_ldata, this_lparam;
249 int tot_data = 0, tot_param = 0;
250 char *outdata, *outparam;
251 char *p;
252
253 this_lparam = MIN (lparam, cli->max_xmit - (500 + lsetup * 2));
254 this_ldata = MIN (ldata, cli->max_xmit - (500 + lsetup * 2 + this_lparam));
255
256 memset (cli->outbuf, '\0', smb_size);
257 set_message (cli->outbuf, 14 + lsetup, 0, True);
258 CVAL (cli->outbuf, smb_com) = trans;
259 SSVAL (cli->outbuf, smb_tid, cli->cnum);
260 cli_setup_packet (cli);
261
262 outparam = smb_buf (cli->outbuf) + (trans == SMBtrans ? pipe_name_len + 1 : 3);
263 outdata = outparam + this_lparam;
264
265
266 SSVAL (cli->outbuf, smb_tpscnt, lparam);
267 SSVAL (cli->outbuf, smb_tdscnt, ldata);
268 SSVAL (cli->outbuf, smb_mprcnt, mparam);
269 SSVAL (cli->outbuf, smb_mdrcnt, mdata);
270 SCVAL (cli->outbuf, smb_msrcnt, msetup);
271 SSVAL (cli->outbuf, smb_flags, flags);
272 SIVAL (cli->outbuf, smb_timeout, 0);
273 SSVAL (cli->outbuf, smb_pscnt, this_lparam);
274 SSVAL (cli->outbuf, smb_psoff, smb_offset (outparam, cli->outbuf));
275 SSVAL (cli->outbuf, smb_dscnt, this_ldata);
276 SSVAL (cli->outbuf, smb_dsoff, smb_offset (outdata, cli->outbuf));
277 SCVAL (cli->outbuf, smb_suwcnt, lsetup);
278 for (i = 0; i < lsetup; i++)
279 SSVAL (cli->outbuf, smb_setup + i * 2, setup[i]);
280 p = smb_buf (cli->outbuf);
281 if (trans == SMBtrans)
282 {
283 memcpy (p, name, pipe_name_len + 1);
284 }
285 else
286 {
287 *p++ = 0;
288 *p++ = 'D';
289 *p++ = ' ';
290 }
291 if (this_lparam)
292 memcpy (outparam, param, this_lparam);
293 if (this_ldata)
294 memcpy (outdata, data, this_ldata);
295 set_message (cli->outbuf, 14 + lsetup,
296 PTR_DIFF (outdata + this_ldata, smb_buf (cli->outbuf)), False);
297
298 show_msg (cli->outbuf);
299 cli_send_smb (cli);
300
301 if (this_ldata < ldata || this_lparam < lparam)
302 {
303
304 if (!cli_receive_smb (cli) || CVAL (cli->inbuf, smb_rcls) != 0)
305 {
306 return (False);
307 }
308
309 tot_data = this_ldata;
310 tot_param = this_lparam;
311
312 while (tot_data < ldata || tot_param < lparam)
313 {
314 this_lparam = MIN (lparam - tot_param, cli->max_xmit - 500);
315 this_ldata = MIN (ldata - tot_data, cli->max_xmit - (500 + this_lparam));
316
317 set_message (cli->outbuf, trans == SMBtrans ? 8 : 9, 0, True);
318 CVAL (cli->outbuf, smb_com) = trans == SMBtrans ? SMBtranss : SMBtranss2;
319
320 outparam = smb_buf (cli->outbuf);
321 outdata = outparam + this_lparam;
322
323
324 SSVAL (cli->outbuf, smb_tpscnt, lparam);
325 SSVAL (cli->outbuf, smb_tdscnt, ldata);
326 SSVAL (cli->outbuf, smb_spscnt, this_lparam);
327 SSVAL (cli->outbuf, smb_spsoff, smb_offset (outparam, cli->outbuf));
328 SSVAL (cli->outbuf, smb_spsdisp, tot_param);
329 SSVAL (cli->outbuf, smb_sdscnt, this_ldata);
330 SSVAL (cli->outbuf, smb_sdsoff, smb_offset (outdata, cli->outbuf));
331 SSVAL (cli->outbuf, smb_sdsdisp, tot_data);
332 if (trans == SMBtrans2)
333 SSVALS (cli->outbuf, smb_sfid, fid);
334 if (this_lparam)
335 memcpy (outparam, param, this_lparam);
336 if (this_ldata)
337 memcpy (outdata, data, this_ldata);
338 set_message (cli->outbuf, trans == SMBtrans ? 8 : 9,
339 PTR_DIFF (outdata + this_ldata, smb_buf (cli->outbuf)), False);
340
341 show_msg (cli->outbuf);
342 cli_send_smb (cli);
343
344 tot_data += this_ldata;
345 tot_param += this_lparam;
346 }
347 }
348
349 return (True);
350 }
351
352
353
354
355
356 static BOOL
357 cli_receive_trans (struct cli_state *cli, int trans,
358 char **param, int *param_len, char **data, int *data_len)
359 {
360 int total_data = 0;
361 int total_param = 0;
362 int this_data, this_param;
363 uint8 eclass;
364 uint32 ecode;
365
366 *data_len = *param_len = 0;
367
368 if (!cli_receive_smb (cli))
369 return False;
370
371 show_msg (cli->inbuf);
372
373
374 if (CVAL (cli->inbuf, smb_com) != trans)
375 {
376 DEBUG (0, ("Expected %s response, got command 0x%02x\n",
377 trans == SMBtrans ? "SMBtrans" : "SMBtrans2", CVAL (cli->inbuf, smb_com)));
378 return (False);
379 }
380
381
382
383
384
385
386
387 if (cli_error (cli, &eclass, &ecode, NULL))
388 {
389 if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
390 return (False);
391 }
392
393
394 total_data = SVAL (cli->inbuf, smb_tdrcnt);
395 total_param = SVAL (cli->inbuf, smb_tprcnt);
396
397
398 *data = Realloc (*data, total_data);
399 *param = Realloc (*param, total_param);
400
401 while (1)
402 {
403 this_data = SVAL (cli->inbuf, smb_drcnt);
404 this_param = SVAL (cli->inbuf, smb_prcnt);
405
406 if (this_data + *data_len > total_data || this_param + *param_len > total_param)
407 {
408 DEBUG (1, ("Data overflow in cli_receive_trans\n"));
409 return False;
410 }
411
412 if (this_data)
413 memcpy (*data + SVAL (cli->inbuf, smb_drdisp),
414 smb_base (cli->inbuf) + SVAL (cli->inbuf, smb_droff), this_data);
415 if (this_param)
416 memcpy (*param + SVAL (cli->inbuf, smb_prdisp),
417 smb_base (cli->inbuf) + SVAL (cli->inbuf, smb_proff), this_param);
418 *data_len += this_data;
419 *param_len += this_param;
420
421
422 total_data = SVAL (cli->inbuf, smb_tdrcnt);
423 total_param = SVAL (cli->inbuf, smb_tprcnt);
424
425 if (total_data <= *data_len && total_param <= *param_len)
426 break;
427
428 if (!cli_receive_smb (cli))
429 return False;
430
431 show_msg (cli->inbuf);
432
433
434 if (CVAL (cli->inbuf, smb_com) != trans)
435 {
436 DEBUG (0, ("Expected %s response, got command 0x%02x\n",
437 trans == SMBtrans ? "SMBtrans" : "SMBtrans2", CVAL (cli->inbuf, smb_com)));
438 return (False);
439 }
440 if (cli_error (cli, &eclass, &ecode, NULL))
441 {
442 if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
443 return (False);
444 }
445 }
446
447 return (True);
448 }
449
450 #if 0
451
452
453
454 BOOL
455 cli_api_pipe (struct cli_state * cli, char *pipe_name, int pipe_name_len,
456 uint16 * setup, uint32 setup_count, uint32 max_setup_count,
457 char *params, uint32 param_count, uint32 max_param_count,
458 char *data, uint32 data_count, uint32 max_data_count,
459 char **rparam, uint32 * rparam_count, char **rdata, uint32 * rdata_count)
460 {
461 if (pipe_name_len == 0)
462 pipe_name_len = strlen (pipe_name);
463
464 cli_send_trans (cli, SMBtrans, pipe_name, pipe_name_len, 0, 0,
465 setup, setup_count, max_setup_count,
466 params, param_count, max_param_count, data, data_count, max_data_count);
467
468 return (cli_receive_trans (cli, SMBtrans,
469 rparam, (int *) rparam_count, rdata, (int *) rdata_count));
470 }
471 #endif
472
473
474
475
476 BOOL
477 cli_api (struct cli_state *cli,
478 char *param, int prcnt, int mprcnt,
479 char *data, int drcnt, int mdrcnt, char **rparam, int *rprcnt, char **rdata, int *rdrcnt)
480 {
481 cli_send_trans (cli, SMBtrans, PIPE_LANMAN, strlen (PIPE_LANMAN),
482 0, 0,
483 NULL, 0, 0,
484 param, prcnt, mprcnt,
485 data, drcnt, mdrcnt
486 );
487
488 return (cli_receive_trans (cli, SMBtrans, rparam, rprcnt, rdata, rdrcnt));
489 }
490
491 #if 0
492
493
494
495 BOOL
496 cli_NetWkstaUserLogon (struct cli_state * cli, char *user, char *workstation)
497 {
498 char *rparam = NULL;
499 char *rdata = NULL;
500 char *p;
501 int rdrcnt, rprcnt;
502 pstring param;
503
504 memset (param, 0, sizeof (param));
505
506
507 p = param;
508 SSVAL (p, 0, 132);
509 p += 2;
510 pstrcpy (p, "OOWb54WrLh");
511 p = skip_string (p, 1);
512 pstrcpy (p, "WB21BWDWWDDDDDDDzzzD");
513 p = skip_string (p, 1);
514 SSVAL (p, 0, 1);
515 p += 2;
516 pstrcpy (p, user);
517 strupper (p);
518 p += 21;
519 p++;
520 p += 15;
521 p++;
522 pstrcpy (p, workstation);
523 strupper (p);
524 p += 16;
525 SSVAL (p, 0, CLI_BUFFER_SIZE);
526 p += 2;
527 SSVAL (p, 0, CLI_BUFFER_SIZE);
528 p += 2;
529
530 if (cli_api (cli, param, PTR_DIFF (p, param), 1024,
531 NULL, 0, CLI_BUFFER_SIZE,
532 &rparam, &rprcnt,
533 &rdata, &rdrcnt
534 ))
535 {
536 cli->rap_error = SVAL (rparam, 0);
537 p = rdata;
538
539 if (cli->rap_error == 0)
540 {
541 DEBUG (4, ("NetWkstaUserLogon success\n"));
542 cli->privileges = SVAL (p, 24);
543 fstrcpy (cli->eff_name, p + 2);
544 }
545 else
546 {
547 DEBUG (1, ("NetwkstaUserLogon gave error %d\n", cli->rap_error));
548 }
549 }
550
551 if (rparam)
552 free (rparam);
553 if (rdata)
554 free (rdata);
555 return (cli->rap_error == 0);
556 }
557 #endif
558
559
560
561
562 int
563 cli_RNetShareEnum (struct cli_state *cli, void (*fn) (const char *, uint32, const char *, void *),
564 void *state)
565 {
566 char *rparam = NULL;
567 char *rdata = NULL;
568 char *p;
569 int rdrcnt, rprcnt;
570 pstring param;
571 int count = -1;
572
573
574 p = param;
575 SSVAL (p, 0, 0);
576 p += 2;
577 pstrcpy (p, "WrLeh");
578 p = skip_string (p, 1);
579 pstrcpy (p, "B13BWz");
580 p = skip_string (p, 1);
581 SSVAL (p, 0, 1);
582
583
584
585
586 SSVAL (p, 2, 0xFFE0);
587 p += 4;
588
589 if (cli_api (cli, param, PTR_DIFF (p, param), 1024,
590 NULL, 0, 0xFFE0,
591 &rparam, &rprcnt,
592 &rdata, &rdrcnt))
593 {
594 int res = SVAL (rparam, 0);
595 int converter = SVAL (rparam, 2);
596 int i;
597
598 if (res == 0 || res == ERRmoredata)
599 {
600 count = SVAL (rparam, 4);
601 p = rdata;
602
603 for (i = 0; i < count; i++, p += 20)
604 {
605 char *sname = p;
606 int type = SVAL (p, 14);
607 int comment_offset = IVAL (p, 16) & 0xFFFF;
608 const char *cmnt = comment_offset ? (rdata + comment_offset - converter) : "";
609 fn (sname, type, cmnt, state);
610 }
611 }
612 else
613 {
614 DEBUG (4, ("NetShareEnum res=%d\n", res));
615 }
616 }
617 else
618 {
619 DEBUG (4, ("NetShareEnum failed\n"));
620 }
621
622 if (rparam)
623 free (rparam);
624 if (rdata)
625 free (rdata);
626
627 return count;
628 }
629
630
631
632
633
634
635
636
637
638 BOOL
639 cli_NetServerEnum (struct cli_state * cli, char *workgroup, uint32 stype,
640 void (*fn) (const char *, uint32, const char *, void *), void *state)
641 {
642 char *rparam = NULL;
643 char *rdata = NULL;
644 int rdrcnt, rprcnt;
645 char *p;
646 pstring param;
647 int uLevel = 1;
648 int count = -1;
649
650
651 p = param;
652 SSVAL (p, 0, 0x68);
653 p += 2;
654 pstrcpy (p, "WrLehDz");
655 p = skip_string (p, 1);
656
657 pstrcpy (p, "B16BBDz");
658
659 p = skip_string (p, 1);
660 SSVAL (p, 0, uLevel);
661 SSVAL (p, 2, CLI_BUFFER_SIZE);
662 p += 4;
663 SIVAL (p, 0, stype);
664 p += 4;
665
666 pstrcpy (p, workgroup);
667 p = skip_string (p, 1);
668
669 if (cli_api (cli, param, PTR_DIFF (p, param), 8,
670 NULL, 0, CLI_BUFFER_SIZE,
671 &rparam, &rprcnt,
672 &rdata, &rdrcnt
673 ))
674 {
675 int res = SVAL (rparam, 0);
676 int converter = SVAL (rparam, 2);
677 int i;
678
679 if (res == 0 || res == ERRmoredata)
680 {
681 count = SVAL (rparam, 4);
682 p = rdata;
683
684 for (i = 0; i < count; i++, p += 26)
685 {
686 char *sname = p;
687 int comment_offset = (IVAL (p, 22) & 0xFFFF) - converter;
688 const char *cmnt = comment_offset ? (rdata + comment_offset) : "";
689 if (comment_offset < 0 || comment_offset > rdrcnt)
690 continue;
691
692 stype = IVAL (p, 18) & ~SV_TYPE_LOCAL_LIST_ONLY;
693
694 fn (sname, stype, cmnt, state);
695 }
696 }
697 }
698
699 if (rparam)
700 free (rparam);
701 if (rdata)
702 free (rdata);
703
704 return (count > 0);
705 }
706
707
708
709
710 static struct
711 {
712 int prot;
713 const char *name;
714 }
715 const prots[] = {
716 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
717 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
718 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
719 {PROTOCOL_LANMAN1, "LANMAN1.0"},
720 {PROTOCOL_LANMAN2, "LM1.2X002"},
721 {PROTOCOL_LANMAN2, "Samba"},
722 {PROTOCOL_NT1, "NT LANMAN 1.0"},
723 {PROTOCOL_NT1, "NT LM 0.12"},
724 {-1, NULL}
725 };
726
727
728
729
730
731 BOOL
732 cli_session_setup (struct cli_state *cli,
733 char *user,
734 char *pass, int passlen, char *ntpass, int ntpasslen, char *workgroup)
735 {
736 char *p;
737 fstring pword, ntpword;
738
739 if (cli->protocol < PROTOCOL_LANMAN1)
740 return True;
741
742 if ((size_t) passlen > sizeof (pword) - 1 || (size_t) ntpasslen > sizeof (ntpword) - 1)
743 {
744 return False;
745 }
746
747 if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0'))
748 {
749
750 pword[0] = '\0';
751 ntpword[0] = '\0';
752 }
753 else
754 {
755 if ((cli->sec_mode & 2) && passlen != 24)
756 {
757 passlen = 24;
758 ntpasslen = 24;
759 SMBencrypt ((uchar *) pass, (uchar *) cli->cryptkey, (uchar *) pword);
760 SMBNTencrypt ((uchar *) ntpass, (uchar *) cli->cryptkey, (uchar *) ntpword);
761 }
762 else
763 {
764 fstrcpy (pword, pass);
765 fstrcpy (ntpword, "");
766 ntpasslen = 0;
767 }
768 }
769
770
771 if (!(cli->sec_mode & 1))
772 {
773 fstrcpy (pword, "");
774 passlen = 1;
775 fstrcpy (ntpword, "");
776 ntpasslen = 1;
777 }
778
779
780 memset (cli->outbuf, '\0', smb_size);
781
782 if (cli->protocol < PROTOCOL_NT1)
783 {
784 set_message (cli->outbuf, 10, 1 + strlen (user) + passlen, True);
785 CVAL (cli->outbuf, smb_com) = SMBsesssetupX;
786 cli_setup_packet (cli);
787
788 CVAL (cli->outbuf, smb_vwv0) = 0xFF;
789 SSVAL (cli->outbuf, smb_vwv2, cli->max_xmit);
790 SSVAL (cli->outbuf, smb_vwv3, 2);
791 SSVAL (cli->outbuf, smb_vwv4, 1);
792 SIVAL (cli->outbuf, smb_vwv5, cli->sesskey);
793 SSVAL (cli->outbuf, smb_vwv7, passlen);
794 p = smb_buf (cli->outbuf);
795 memcpy (p, pword, passlen);
796 p += passlen;
797 pstrcpy (p, user);
798 strupper (p);
799 unix_to_dos (p, True);
800 }
801 else
802 {
803 set_message (cli->outbuf, 13, 0, True);
804 CVAL (cli->outbuf, smb_com) = SMBsesssetupX;
805 cli_setup_packet (cli);
806
807 CVAL (cli->outbuf, smb_vwv0) = 0xFF;
808 SSVAL (cli->outbuf, smb_vwv2, CLI_BUFFER_SIZE);
809 SSVAL (cli->outbuf, smb_vwv3, 2);
810 SSVAL (cli->outbuf, smb_vwv4, cli->pid);
811 SIVAL (cli->outbuf, smb_vwv5, cli->sesskey);
812 SSVAL (cli->outbuf, smb_vwv7, passlen);
813 SSVAL (cli->outbuf, smb_vwv8, ntpasslen);
814 SSVAL (cli->outbuf, smb_vwv11, 0);
815 p = smb_buf (cli->outbuf);
816 memcpy (p, pword, passlen);
817 p += SVAL (cli->outbuf, smb_vwv7);
818 memcpy (p, ntpword, ntpasslen);
819 p += SVAL (cli->outbuf, smb_vwv8);
820 pstrcpy (p, user);
821 strupper (p);
822 unix_to_dos (p, True);
823 p = skip_string (p, 1);
824 pstrcpy (p, workgroup);
825 strupper (p);
826 p = skip_string (p, 1);
827 pstrcpy (p, "Unix");
828 p = skip_string (p, 1);
829 pstrcpy (p, "Samba");
830 p = skip_string (p, 1);
831 set_message (cli->outbuf, 13, PTR_DIFF (p, smb_buf (cli->outbuf)), False);
832 }
833
834 cli_send_smb (cli);
835 if (!cli_receive_smb (cli))
836 return False;
837
838 show_msg (cli->inbuf);
839
840 if (CVAL (cli->inbuf, smb_rcls) != 0)
841 {
842 return False;
843 }
844
845
846 cli->vuid = SVAL (cli->inbuf, smb_uid);
847
848 if (cli->protocol >= PROTOCOL_NT1)
849 {
850
851
852
853
854 char *server_domain, *server_os, *server_type;
855 server_os = smb_buf (cli->inbuf);
856 server_type = skip_string (server_os, 1);
857 server_domain = skip_string (server_type, 1);
858 fstrcpy (cli->server_os, server_os);
859 fstrcpy (cli->server_type, server_type);
860 fstrcpy (cli->server_domain, server_domain);
861 }
862
863 fstrcpy (cli->user_name, user);
864
865 return True;
866 }
867
868
869
870
871 #if 0
872 BOOL
873 cli_ulogoff (struct cli_state * cli)
874 {
875 memset (cli->outbuf, '\0', smb_size);
876 set_message (cli->outbuf, 2, 0, True);
877 CVAL (cli->outbuf, smb_com) = SMBulogoffX;
878 cli_setup_packet (cli);
879 SSVAL (cli->outbuf, smb_vwv0, 0xFF);
880 SSVAL (cli->outbuf, smb_vwv2, 0);
881
882 cli_send_smb (cli);
883 if (!cli_receive_smb (cli))
884 return False;
885
886 return CVAL (cli->inbuf, smb_rcls) == 0;
887 }
888 #endif
889
890
891
892
893 BOOL
894 cli_send_tconX (struct cli_state * cli,
895 const char *share, const char *dev, const char *pass, int passlen)
896 {
897 fstring fullshare, pword;
898 char *p;
899 memset (cli->outbuf, '\0', smb_size);
900 memset (cli->inbuf, '\0', smb_size);
901
902 fstrcpy (cli->share, share);
903
904
905 if (cli->sec_mode & 1)
906 {
907 passlen = 1;
908 pass = "";
909 }
910
911 if ((cli->sec_mode & 2) && *pass && passlen != 24)
912 {
913 passlen = 24;
914 SMBencrypt ((uchar *) pass, (uchar *) cli->cryptkey, (uchar *) pword);
915 }
916 else
917 {
918 memcpy (pword, pass, passlen);
919 }
920
921 slprintf (fullshare, sizeof (fullshare) - 1, "\\\\%s\\%s", cli->desthost, share);
922 unix_to_dos (fullshare, True);
923 strupper (fullshare);
924
925 set_message (cli->outbuf, 4, 2 + strlen (fullshare) + passlen + strlen (dev), True);
926 CVAL (cli->outbuf, smb_com) = SMBtconX;
927 cli_setup_packet (cli);
928
929 SSVAL (cli->outbuf, smb_vwv0, 0xFF);
930 SSVAL (cli->outbuf, smb_vwv3, passlen);
931
932 p = smb_buf (cli->outbuf);
933 memcpy (p, pword, passlen);
934 p += passlen;
935 fstrcpy (p, fullshare);
936 p = skip_string (p, 1);
937 pstrcpy (p, dev);
938
939 SCVAL (cli->inbuf, smb_rcls, 1);
940
941 cli_send_smb (cli);
942 if (!cli_receive_smb (cli))
943 return False;
944
945 if (CVAL (cli->inbuf, smb_rcls) != 0)
946 {
947 return False;
948 }
949
950 fstrcpy (cli->dev, "A:");
951
952 if (cli->protocol >= PROTOCOL_NT1)
953 {
954 fstrcpy (cli->dev, smb_buf (cli->inbuf));
955 }
956
957 if (strcasecmp (share, "IPC$") == 0)
958 {
959 fstrcpy (cli->dev, "IPC");
960 }
961
962
963 if (cli->protocol >= PROTOCOL_NT1 && smb_buflen (cli->inbuf) == 3)
964 {
965
966 cli->win95 = True;
967 }
968
969 cli->cnum = SVAL (cli->inbuf, smb_tid);
970 return True;
971 }
972
973 #if 0
974
975
976
977 BOOL
978 cli_tdis (struct cli_state * cli)
979 {
980 memset (cli->outbuf, '\0', smb_size);
981 set_message (cli->outbuf, 0, 0, True);
982 CVAL (cli->outbuf, smb_com) = SMBtdis;
983 SSVAL (cli->outbuf, smb_tid, cli->cnum);
984 cli_setup_packet (cli);
985
986 cli_send_smb (cli);
987 if (!cli_receive_smb (cli))
988 return False;
989
990 return CVAL (cli->inbuf, smb_rcls) == 0;
991 }
992 #endif
993
994
995
996
997 BOOL
998 cli_rename (struct cli_state * cli, char *fname_src, char *fname_dst)
999 {
1000 char *p;
1001
1002 memset (cli->outbuf, '\0', smb_size);
1003 memset (cli->inbuf, '\0', smb_size);
1004
1005 set_message (cli->outbuf, 1, 4 + strlen (fname_src) + strlen (fname_dst), True);
1006
1007 CVAL (cli->outbuf, smb_com) = SMBmv;
1008 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1009 cli_setup_packet (cli);
1010
1011 SSVAL (cli->outbuf, smb_vwv0, aSYSTEM | aHIDDEN);
1012
1013 p = smb_buf (cli->outbuf);
1014 *p++ = 4;
1015 pstrcpy (p, fname_src);
1016 p = skip_string (p, 1);
1017 *p++ = 4;
1018 pstrcpy (p, fname_dst);
1019
1020 cli_send_smb (cli);
1021 if (!cli_receive_smb (cli))
1022 {
1023 return False;
1024 }
1025
1026 if (CVAL (cli->inbuf, smb_rcls) != 0)
1027 {
1028 return False;
1029 }
1030
1031 return True;
1032 }
1033
1034
1035
1036
1037 BOOL
1038 cli_unlink (struct cli_state * cli, char *fname)
1039 {
1040 char *p;
1041
1042 memset (cli->outbuf, '\0', smb_size);
1043 memset (cli->inbuf, '\0', smb_size);
1044
1045 set_message (cli->outbuf, 1, 2 + strlen (fname), True);
1046
1047 CVAL (cli->outbuf, smb_com) = SMBunlink;
1048 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1049 cli_setup_packet (cli);
1050
1051 SSVAL (cli->outbuf, smb_vwv0, aSYSTEM | aHIDDEN);
1052
1053 p = smb_buf (cli->outbuf);
1054 *p++ = 4;
1055 pstrcpy (p, fname);
1056
1057 cli_send_smb (cli);
1058 if (!cli_receive_smb (cli))
1059 {
1060 return False;
1061 }
1062
1063 if (CVAL (cli->inbuf, smb_rcls) != 0)
1064 {
1065 return False;
1066 }
1067
1068 return True;
1069 }
1070
1071
1072
1073
1074 BOOL
1075 cli_mkdir (struct cli_state * cli, char *dname)
1076 {
1077 char *p;
1078
1079 memset (cli->outbuf, '\0', smb_size);
1080 memset (cli->inbuf, '\0', smb_size);
1081
1082 set_message (cli->outbuf, 0, 2 + strlen (dname), True);
1083
1084 CVAL (cli->outbuf, smb_com) = SMBmkdir;
1085 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1086 cli_setup_packet (cli);
1087
1088 p = smb_buf (cli->outbuf);
1089 *p++ = 4;
1090 pstrcpy (p, dname);
1091
1092 cli_send_smb (cli);
1093 if (!cli_receive_smb (cli))
1094 {
1095 return False;
1096 }
1097
1098 if (CVAL (cli->inbuf, smb_rcls) != 0)
1099 {
1100 return False;
1101 }
1102
1103 return True;
1104 }
1105
1106
1107
1108
1109 BOOL
1110 cli_rmdir (struct cli_state * cli, char *dname)
1111 {
1112 char *p;
1113
1114 memset (cli->outbuf, '\0', smb_size);
1115 memset (cli->inbuf, '\0', smb_size);
1116
1117 set_message (cli->outbuf, 0, 2 + strlen (dname), True);
1118
1119 CVAL (cli->outbuf, smb_com) = SMBrmdir;
1120 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1121 cli_setup_packet (cli);
1122
1123 p = smb_buf (cli->outbuf);
1124 *p++ = 4;
1125 pstrcpy (p, dname);
1126
1127 cli_send_smb (cli);
1128 if (!cli_receive_smb (cli))
1129 {
1130 return False;
1131 }
1132
1133 if (CVAL (cli->inbuf, smb_rcls) != 0)
1134 {
1135 return False;
1136 }
1137
1138 return True;
1139 }
1140
1141 #if 0
1142
1143
1144
1145 int
1146 cli_nt_create (struct cli_state *cli, char *fname)
1147 {
1148 char *p;
1149
1150 memset (cli->outbuf, '\0', smb_size);
1151 memset (cli->inbuf, '\0', smb_size);
1152
1153 set_message (cli->outbuf, 24, 1 + strlen (fname), True);
1154
1155 CVAL (cli->outbuf, smb_com) = SMBntcreateX;
1156 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1157 cli_setup_packet (cli);
1158
1159 SSVAL (cli->outbuf, smb_vwv0, 0xFF);
1160 SIVAL (cli->outbuf, smb_ntcreate_Flags, 0x06);
1161 SIVAL (cli->outbuf, smb_ntcreate_RootDirectoryFid, 0x0);
1162 SIVAL (cli->outbuf, smb_ntcreate_DesiredAccess, 0x2019f);
1163 SIVAL (cli->outbuf, smb_ntcreate_FileAttributes, 0x0);
1164 SIVAL (cli->outbuf, smb_ntcreate_ShareAccess, 0x03);
1165 SIVAL (cli->outbuf, smb_ntcreate_CreateDisposition, 0x01);
1166 SIVAL (cli->outbuf, smb_ntcreate_CreateOptions, 0x0);
1167 SIVAL (cli->outbuf, smb_ntcreate_ImpersonationLevel, 0x02);
1168 SSVAL (cli->outbuf, smb_ntcreate_NameLength, strlen (fname));
1169
1170 p = smb_buf (cli->outbuf);
1171 pstrcpy (p, fname);
1172 p = skip_string (p, 1);
1173
1174 cli_send_smb (cli);
1175 if (!cli_receive_smb (cli))
1176 {
1177 return -1;
1178 }
1179
1180 if (CVAL (cli->inbuf, smb_rcls) != 0)
1181 {
1182 return -1;
1183 }
1184
1185 return SVAL (cli->inbuf, smb_vwv2 + 1);
1186 }
1187 #endif
1188
1189
1190
1191
1192 int
1193 cli_open (struct cli_state *cli, char *fname, int flags, int share_mode)
1194 {
1195 char *p;
1196 unsigned openfn = 0;
1197 unsigned accessmode = 0;
1198
1199
1200
1201 if ((flags & O_ACCMODE) == O_WRONLY && strncmp (cli->dev, "LPT", 3))
1202 {
1203 flags = (flags & ~O_ACCMODE) | O_RDWR;
1204 }
1205
1206 if (flags & O_CREAT)
1207 openfn |= (1 << 4);
1208 if (!(flags & O_EXCL))
1209 {
1210 if (flags & O_TRUNC)
1211 openfn |= (1 << 1);
1212 else
1213 openfn |= (1 << 0);
1214 }
1215
1216 accessmode = (share_mode << 4);
1217
1218 if ((flags & O_ACCMODE) == O_RDWR)
1219 {
1220 accessmode |= 2;
1221 }
1222 else if ((flags & O_ACCMODE) == O_WRONLY)
1223 {
1224 accessmode |= 1;
1225 }
1226
1227 #if defined(O_SYNC)
1228 if ((flags & O_SYNC) == O_SYNC)
1229 {
1230 accessmode |= (1 << 14);
1231 }
1232 #endif
1233
1234 memset (cli->outbuf, '\0', smb_size);
1235 memset (cli->inbuf, '\0', smb_size);
1236
1237 set_message (cli->outbuf, 15, 1 + strlen (fname), True);
1238
1239 CVAL (cli->outbuf, smb_com) = SMBopenX;
1240 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1241 cli_setup_packet (cli);
1242
1243 SSVAL (cli->outbuf, smb_vwv0, 0xFF);
1244 SSVAL (cli->outbuf, smb_vwv2, 0);
1245 SSVAL (cli->outbuf, smb_vwv3, accessmode);
1246 SSVAL (cli->outbuf, smb_vwv4, aSYSTEM | aHIDDEN);
1247 SSVAL (cli->outbuf, smb_vwv5, 0);
1248 SSVAL (cli->outbuf, smb_vwv8, openfn);
1249
1250 p = smb_buf (cli->outbuf);
1251 pstrcpy (p, fname);
1252 p = skip_string (p, 1);
1253
1254 cli_send_smb (cli);
1255 if (!cli_receive_smb (cli))
1256 {
1257 return -1;
1258 }
1259
1260 if (CVAL (cli->inbuf, smb_rcls) != 0)
1261 {
1262 return -1;
1263 }
1264
1265 return SVAL (cli->inbuf, smb_vwv2);
1266 }
1267
1268
1269
1270
1271
1272
1273
1274 BOOL
1275 cli_close (struct cli_state * cli, int fnum)
1276 {
1277 memset (cli->outbuf, '\0', smb_size);
1278 memset (cli->inbuf, '\0', smb_size);
1279
1280 set_message (cli->outbuf, 3, 0, True);
1281
1282 CVAL (cli->outbuf, smb_com) = SMBclose;
1283 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1284 cli_setup_packet (cli);
1285
1286 SSVAL (cli->outbuf, smb_vwv0, fnum);
1287 SIVALS (cli->outbuf, smb_vwv1, -1);
1288
1289 cli_send_smb (cli);
1290 if (!cli_receive_smb (cli))
1291 {
1292 return False;
1293 }
1294
1295 if (CVAL (cli->inbuf, smb_rcls) != 0)
1296 {
1297 return False;
1298 }
1299
1300 return True;
1301 }
1302
1303 #if 0
1304
1305
1306
1307 BOOL
1308 cli_lock (struct cli_state * cli, int fnum, uint32 offset, uint32 len, int timeout)
1309 {
1310 char *p;
1311 int saved_timeout = cli->timeout;
1312
1313 memset (cli->outbuf, '\0', smb_size);
1314 memset (cli->inbuf, '\0', smb_size);
1315
1316 set_message (cli->outbuf, 8, 10, True);
1317
1318 CVAL (cli->outbuf, smb_com) = SMBlockingX;
1319 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1320 cli_setup_packet (cli);
1321
1322 CVAL (cli->outbuf, smb_vwv0) = 0xFF;
1323 SSVAL (cli->outbuf, smb_vwv2, fnum);
1324 CVAL (cli->outbuf, smb_vwv3) = 0;
1325 SIVALS (cli->outbuf, smb_vwv4, timeout);
1326 SSVAL (cli->outbuf, smb_vwv6, 0);
1327 SSVAL (cli->outbuf, smb_vwv7, 1);
1328
1329 p = smb_buf (cli->outbuf);
1330 SSVAL (p, 0, cli->pid);
1331 SIVAL (p, 2, offset);
1332 SIVAL (p, 6, len);
1333 cli_send_smb (cli);
1334
1335 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout;
1336
1337 if (!cli_receive_smb (cli))
1338 {
1339 cli->timeout = saved_timeout;
1340 return False;
1341 }
1342
1343 cli->timeout = saved_timeout;
1344
1345 if (CVAL (cli->inbuf, smb_rcls) != 0)
1346 {
1347 return False;
1348 }
1349
1350 return True;
1351 }
1352
1353
1354
1355
1356 BOOL
1357 cli_unlock (struct cli_state * cli, int fnum, uint32 offset, uint32 len, int timeout)
1358 {
1359 char *p;
1360
1361 memset (cli->outbuf, '\0', smb_size);
1362 memset (cli->inbuf, '\0', smb_size);
1363
1364 set_message (cli->outbuf, 8, 10, True);
1365
1366 CVAL (cli->outbuf, smb_com) = SMBlockingX;
1367 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1368 cli_setup_packet (cli);
1369
1370 CVAL (cli->outbuf, smb_vwv0) = 0xFF;
1371 SSVAL (cli->outbuf, smb_vwv2, fnum);
1372 CVAL (cli->outbuf, smb_vwv3) = 0;
1373 SIVALS (cli->outbuf, smb_vwv4, timeout);
1374 SSVAL (cli->outbuf, smb_vwv6, 1);
1375 SSVAL (cli->outbuf, smb_vwv7, 0);
1376
1377 p = smb_buf (cli->outbuf);
1378 SSVAL (p, 0, cli->pid);
1379 SIVAL (p, 2, offset);
1380 SIVAL (p, 6, len);
1381
1382 cli_send_smb (cli);
1383 if (!cli_receive_smb (cli))
1384 {
1385 return False;
1386 }
1387
1388 if (CVAL (cli->inbuf, smb_rcls) != 0)
1389 {
1390 return False;
1391 }
1392
1393 return True;
1394 }
1395 #endif
1396
1397
1398
1399
1400
1401 static void
1402 cli_issue_read (struct cli_state *cli, int fnum, off_t offset, size_t size, int i)
1403 {
1404 memset (cli->outbuf, '\0', smb_size);
1405 memset (cli->inbuf, '\0', smb_size);
1406
1407 set_message (cli->outbuf, 10, 0, True);
1408
1409 CVAL (cli->outbuf, smb_com) = SMBreadX;
1410 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1411 cli_setup_packet (cli);
1412
1413 CVAL (cli->outbuf, smb_vwv0) = 0xFF;
1414 SSVAL (cli->outbuf, smb_vwv2, fnum);
1415 SIVAL (cli->outbuf, smb_vwv3, offset);
1416 SSVAL (cli->outbuf, smb_vwv5, size);
1417 SSVAL (cli->outbuf, smb_vwv6, size);
1418 SSVAL (cli->outbuf, smb_mid, cli->mid + i);
1419
1420 cli_send_smb (cli);
1421 }
1422
1423
1424
1425
1426 size_t
1427 cli_read (struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
1428 {
1429 char *p;
1430 int total = -1;
1431 int issued = 0;
1432 int received = 0;
1433 int mpx = MAX (cli->max_mux - 1, 1);
1434 int block = (cli->max_xmit - (smb_size + 32)) & ~1023;
1435 int mid;
1436 int blocks = (size + (block - 1)) / block;
1437
1438 if (size == 0)
1439 return 0;
1440
1441 while (received < blocks)
1442 {
1443 int size2;
1444
1445 while (issued - received < mpx && issued < blocks)
1446 {
1447 int size1 = MIN (block, (int) size - issued * block);
1448 cli_issue_read (cli, fnum, offset + issued * block, size1, issued);
1449 issued++;
1450 }
1451
1452 if (!cli_receive_smb (cli))
1453 {
1454 return total;
1455 }
1456
1457 received++;
1458 mid = SVAL (cli->inbuf, smb_mid) - cli->mid;
1459 size2 = SVAL (cli->inbuf, smb_vwv5);
1460
1461 if (CVAL (cli->inbuf, smb_rcls) != 0)
1462 {
1463 blocks = MIN (blocks, mid - 1);
1464 continue;
1465 }
1466
1467 if (size2 <= 0)
1468 {
1469 blocks = MIN (blocks, mid - 1);
1470
1471 total = MAX (total, 0);
1472 continue;
1473 }
1474
1475 if (size2 > block)
1476 {
1477 DEBUG (0, ("server returned more than we wanted!\n"));
1478 exit (1);
1479 }
1480 if (mid >= issued)
1481 {
1482 DEBUG (0, ("invalid mid from server!\n"));
1483 exit (1);
1484 }
1485 p = smb_base (cli->inbuf) + SVAL (cli->inbuf, smb_vwv6);
1486
1487 memcpy (buf + mid * block, p, size2);
1488
1489 total = MAX (total, mid * block + size2);
1490 }
1491
1492 while (received < issued)
1493 {
1494 cli_receive_smb (cli);
1495 received++;
1496 }
1497
1498 return total;
1499 }
1500
1501
1502
1503
1504
1505 static void
1506 cli_issue_write (struct cli_state *cli, int fnum, off_t offset, uint16 mode, const char *buf,
1507 size_t size, int i)
1508 {
1509 char *p;
1510
1511 memset (cli->outbuf, '\0', smb_size);
1512 memset (cli->inbuf, '\0', smb_size);
1513
1514 set_message (cli->outbuf, 12, size, True);
1515
1516 CVAL (cli->outbuf, smb_com) = SMBwriteX;
1517 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1518 cli_setup_packet (cli);
1519
1520 CVAL (cli->outbuf, smb_vwv0) = 0xFF;
1521 SSVAL (cli->outbuf, smb_vwv2, fnum);
1522
1523 SIVAL (cli->outbuf, smb_vwv3, offset);
1524 SIVAL (cli->outbuf, smb_vwv5, IS_BITS_SET_ALL (mode, 0x0008) ? 0xFFFFFFFF : 0);
1525 SSVAL (cli->outbuf, smb_vwv7, mode);
1526
1527 SSVAL (cli->outbuf, smb_vwv8, IS_BITS_SET_ALL (mode, 0x0008) ? size : 0);
1528 SSVAL (cli->outbuf, smb_vwv10, size);
1529 SSVAL (cli->outbuf, smb_vwv11, smb_buf (cli->outbuf) - smb_base (cli->outbuf));
1530
1531 p = smb_base (cli->outbuf) + SVAL (cli->outbuf, smb_vwv11);
1532 memcpy (p, buf, size);
1533
1534 SSVAL (cli->outbuf, smb_mid, cli->mid + i);
1535
1536 show_msg (cli->outbuf);
1537 cli_send_smb (cli);
1538 }
1539
1540
1541
1542
1543
1544
1545
1546
1547 ssize_t
1548 cli_write (struct cli_state *cli,
1549 int fnum, uint16 write_mode, const char *buf, off_t offset, size_t size)
1550 {
1551 int bwritten = 0;
1552 int issued = 0;
1553 int received = 0;
1554 int mpx = MAX (cli->max_mux - 1, 1);
1555 int block = (cli->max_xmit - (smb_size + 32)) & ~1023;
1556 int blocks = (size + (block - 1)) / block;
1557
1558 while (received < blocks)
1559 {
1560
1561 while ((issued - received < mpx) && (issued < blocks))
1562 {
1563 int bsent = issued * block;
1564 int size1 = MIN (block, (int) size - bsent);
1565
1566 cli_issue_write (cli, fnum, offset + bsent, write_mode, buf + bsent, size1, issued);
1567 issued++;
1568 }
1569
1570 if (!cli_receive_smb (cli))
1571 {
1572 return bwritten;
1573 }
1574
1575 received++;
1576
1577 if (CVAL (cli->inbuf, smb_rcls) != 0)
1578 {
1579 break;
1580 }
1581
1582 bwritten += SVAL (cli->inbuf, smb_vwv2);
1583 }
1584
1585 while (received < issued && cli_receive_smb (cli))
1586 {
1587 received++;
1588 }
1589
1590 return bwritten;
1591 }
1592
1593 #if 0
1594
1595
1596
1597 ssize_t
1598 cli_smbwrite (struct cli_state * cli, int fnum, const char *buf, off_t offset, size_t size)
1599 {
1600 char *p;
1601
1602 memset (cli->outbuf, '\0', smb_size);
1603 memset (cli->inbuf, '\0', smb_size);
1604
1605 set_message (cli->outbuf, 5, 3 + size, True);
1606
1607 CVAL (cli->outbuf, smb_com) = SMBwrite;
1608 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1609 cli_setup_packet (cli);
1610
1611 SSVAL (cli->outbuf, smb_vwv0, fnum);
1612 SSVAL (cli->outbuf, smb_vwv1, size);
1613 SIVAL (cli->outbuf, smb_vwv2, offset);
1614 SSVAL (cli->outbuf, smb_vwv4, 0);
1615
1616 p = smb_buf (cli->outbuf);
1617 *p++ = 1;
1618 SSVAL (p, 0, size);
1619 memcpy (p + 2, buf, size);
1620
1621 cli_send_smb (cli);
1622 if (!cli_receive_smb (cli))
1623 {
1624 return False;
1625 }
1626
1627 if (CVAL (cli->inbuf, smb_rcls) != 0)
1628 {
1629 return -1;
1630 }
1631
1632 return SVAL (cli->inbuf, smb_vwv0);
1633 }
1634 #endif
1635
1636
1637
1638
1639 BOOL
1640 cli_getattrE (struct cli_state * cli, int fd,
1641 uint16 * attr, size_t * size, time_t * c_time, time_t * a_time, time_t * m_time)
1642 {
1643 memset (cli->outbuf, '\0', smb_size);
1644 memset (cli->inbuf, '\0', smb_size);
1645
1646 set_message (cli->outbuf, 2, 0, True);
1647
1648 CVAL (cli->outbuf, smb_com) = SMBgetattrE;
1649 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1650 cli_setup_packet (cli);
1651
1652 SSVAL (cli->outbuf, smb_vwv0, fd);
1653
1654 cli_send_smb (cli);
1655 if (!cli_receive_smb (cli))
1656 {
1657 return False;
1658 }
1659
1660 if (CVAL (cli->inbuf, smb_rcls) != 0)
1661 {
1662 return False;
1663 }
1664
1665 if (size)
1666 {
1667 *size = IVAL (cli->inbuf, smb_vwv6);
1668 }
1669
1670 if (attr)
1671 {
1672 *attr = SVAL (cli->inbuf, smb_vwv10);
1673 }
1674
1675 if (c_time)
1676 {
1677 *c_time = make_unix_date3 (cli->inbuf + smb_vwv0);
1678 }
1679
1680 if (a_time)
1681 {
1682 *a_time = make_unix_date3 (cli->inbuf + smb_vwv2);
1683 }
1684
1685 if (m_time)
1686 {
1687 *m_time = make_unix_date3 (cli->inbuf + smb_vwv4);
1688 }
1689
1690 return True;
1691 }
1692
1693 #if 0
1694
1695
1696
1697 BOOL
1698 cli_getatr (struct cli_state * cli, char *fname, uint16 * attr, size_t * size, time_t * t)
1699 {
1700 char *p;
1701
1702 memset (cli->outbuf, '\0', smb_size);
1703 memset (cli->inbuf, '\0', smb_size);
1704
1705 set_message (cli->outbuf, 0, strlen (fname) + 2, True);
1706
1707 CVAL (cli->outbuf, smb_com) = SMBgetatr;
1708 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1709 cli_setup_packet (cli);
1710
1711 p = smb_buf (cli->outbuf);
1712 *p = 4;
1713 pstrcpy (p + 1, fname);
1714
1715 cli_send_smb (cli);
1716 if (!cli_receive_smb (cli))
1717 {
1718 return False;
1719 }
1720
1721 if (CVAL (cli->inbuf, smb_rcls) != 0)
1722 {
1723 return False;
1724 }
1725
1726 if (size)
1727 {
1728 *size = IVAL (cli->inbuf, smb_vwv3);
1729 }
1730
1731 if (t)
1732 {
1733 *t = make_unix_date3 (cli->inbuf + smb_vwv1);
1734 }
1735
1736 if (attr)
1737 {
1738 *attr = SVAL (cli->inbuf, smb_vwv0);
1739 }
1740
1741
1742 return True;
1743 }
1744 #endif
1745
1746
1747
1748
1749 BOOL
1750 cli_setatr (struct cli_state * cli, char *fname, uint16 attr, time_t t)
1751 {
1752 char *p;
1753
1754 memset (cli->outbuf, '\0', smb_size);
1755 memset (cli->inbuf, '\0', smb_size);
1756
1757 set_message (cli->outbuf, 8, strlen (fname) + 4, True);
1758
1759 CVAL (cli->outbuf, smb_com) = SMBsetatr;
1760 SSVAL (cli->outbuf, smb_tid, cli->cnum);
1761 cli_setup_packet (cli);
1762
1763 SSVAL (cli->outbuf, smb_vwv0, attr);
1764 put_dos_date3 (cli->outbuf, smb_vwv1, t);
1765
1766 p = smb_buf (cli->outbuf);
1767 *p = 4;
1768 pstrcpy (p + 1, fname);
1769 p = skip_string (p, 1);
1770 *p = 4;
1771
1772 cli_send_smb (cli);
1773 if (!cli_receive_smb (cli))
1774 {
1775 return False;
1776 }
1777
1778 if (CVAL (cli->inbuf, smb_rcls) != 0)
1779 {
1780 return False;
1781 }
1782
1783 return True;
1784 }
1785
1786 #if 0
1787
1788
1789
1790 BOOL
1791 cli_qpathinfo (struct cli_state * cli, const char *fname,
1792 time_t * c_time, time_t * a_time, time_t * m_time, size_t * size, uint16 * mode)
1793 {
1794 int data_len = 0;
1795 int param_len = 0;
1796 uint16 setup = TRANSACT2_QPATHINFO;
1797 pstring param;
1798 char *rparam = NULL, *rdata = NULL;
1799 int count = 8;
1800 BOOL ret;
1801 time_t (*date_fn) (void *);
1802
1803 param_len = strlen (fname) + 7;
1804
1805 memset (param, 0, param_len);
1806 SSVAL (param, 0, SMB_INFO_STANDARD);
1807 pstrcpy (¶m[6], fname);
1808
1809 do
1810 {
1811 ret = (cli_send_trans (cli, SMBtrans2, NULL, 0,
1812 -1, 0,
1813 &setup, 1, 0,
1814 param, param_len, 10,
1815 NULL, data_len, cli->max_xmit
1816 ) && cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len));
1817 if (!ret)
1818 {
1819
1820
1821 uint8 eclass;
1822 uint32 ecode;
1823 cli_error (cli, &eclass, &ecode, NULL);
1824 if (eclass != ERRSRV || ecode != ERRerror)
1825 break;
1826 msleep (100);
1827 }
1828 }
1829 while (count-- && ret == False);
1830
1831 if (!ret || !rdata || data_len < 22)
1832 {
1833 return False;
1834 }
1835
1836 if (cli->win95)
1837 {
1838 date_fn = make_unix_date;
1839 }
1840 else
1841 {
1842 date_fn = make_unix_date2;
1843 }
1844
1845 if (c_time)
1846 {
1847 *c_time = date_fn (rdata + 0);
1848 }
1849 if (a_time)
1850 {
1851 *a_time = date_fn (rdata + 4);
1852 }
1853 if (m_time)
1854 {
1855 *m_time = date_fn (rdata + 8);
1856 }
1857 if (size)
1858 {
1859 *size = IVAL (rdata, 12);
1860 }
1861 if (mode)
1862 {
1863 *mode = SVAL (rdata, l1_attrFile);
1864 }
1865
1866 if (rdata)
1867 free (rdata);
1868 if (rparam)
1869 free (rparam);
1870 return True;
1871 }
1872
1873
1874
1875
1876 BOOL
1877 cli_qpathinfo2 (struct cli_state * cli, const char *fname,
1878 time_t * c_time, time_t * a_time, time_t * m_time,
1879 time_t * w_time, size_t * size, uint16 * mode, SMB_INO_T * ino)
1880 {
1881 int data_len = 0;
1882 int param_len = 0;
1883 uint16 setup = TRANSACT2_QPATHINFO;
1884 pstring param;
1885 char *rparam = NULL, *rdata = NULL;
1886
1887 param_len = strlen (fname) + 7;
1888
1889 memset (param, 0, param_len);
1890 SSVAL (param, 0, SMB_QUERY_FILE_ALL_INFO);
1891 pstrcpy (¶m[6], fname);
1892
1893 if (!cli_send_trans (cli, SMBtrans2, NULL, 0,
1894 -1, 0,
1895 &setup, 1, 0,
1896 param, param_len, 10,
1897 NULL, data_len, cli->max_xmit
1898 ))
1899 {
1900 return False;
1901 }
1902
1903 if (!cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len))
1904 {
1905 return False;
1906 }
1907
1908 if (!rdata || data_len < 22)
1909 {
1910 return False;
1911 }
1912
1913 if (c_time)
1914 {
1915 *c_time = interpret_long_date (rdata + 0) - cli->serverzone;
1916 }
1917 if (a_time)
1918 {
1919 *a_time = interpret_long_date (rdata + 8) - cli->serverzone;
1920 }
1921 if (m_time)
1922 {
1923 *m_time = interpret_long_date (rdata + 16) - cli->serverzone;
1924 }
1925 if (w_time)
1926 {
1927 *w_time = interpret_long_date (rdata + 24) - cli->serverzone;
1928 }
1929 if (mode)
1930 {
1931 *mode = SVAL (rdata, 32);
1932 }
1933 if (size)
1934 {
1935 *size = IVAL (rdata, 48);
1936 }
1937 if (ino)
1938 {
1939 *ino = IVAL (rdata, 64);
1940 }
1941
1942 if (rdata)
1943 free (rdata);
1944 if (rparam)
1945 free (rparam);
1946 return True;
1947 }
1948 #endif
1949
1950
1951
1952
1953 BOOL
1954 cli_qfileinfo (struct cli_state * cli, int fnum,
1955 uint16 * mode, size_t * size,
1956 time_t * c_time, time_t * a_time, time_t * m_time, time_t * w_time, SMB_INO_T * ino)
1957 {
1958 int data_len = 0;
1959 int param_len = 0;
1960 uint16 setup = TRANSACT2_QFILEINFO;
1961 pstring param;
1962 char *rparam = NULL, *rdata = NULL;
1963
1964
1965
1966 if (cli->win95)
1967 return False;
1968
1969 param_len = 4;
1970
1971 memset (param, 0, param_len);
1972 SSVAL (param, 0, fnum);
1973 SSVAL (param, 2, SMB_QUERY_FILE_ALL_INFO);
1974
1975 if (!cli_send_trans (cli, SMBtrans2, NULL, 0,
1976 -1, 0,
1977 &setup, 1, 0,
1978 param, param_len, 2,
1979 NULL, data_len, cli->max_xmit
1980 ))
1981 {
1982 return False;
1983 }
1984
1985 if (!cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len))
1986 {
1987 return False;
1988 }
1989
1990 if (!rdata || data_len < 68)
1991 {
1992 return False;
1993 }
1994
1995 if (c_time)
1996 {
1997 *c_time = interpret_long_date (rdata + 0) - cli->serverzone;
1998 }
1999 if (a_time)
2000 {
2001 *a_time = interpret_long_date (rdata + 8) - cli->serverzone;
2002 }
2003 if (m_time)
2004 {
2005 *m_time = interpret_long_date (rdata + 16) - cli->serverzone;
2006 }
2007 if (w_time)
2008 {
2009 *w_time = interpret_long_date (rdata + 24) - cli->serverzone;
2010 }
2011 if (mode)
2012 {
2013 *mode = SVAL (rdata, 32);
2014 }
2015 if (size)
2016 {
2017 *size = IVAL (rdata, 48);
2018 }
2019 if (ino)
2020 {
2021 *ino = IVAL (rdata, 64);
2022 }
2023
2024 if (rdata)
2025 free (rdata);
2026 if (rparam)
2027 free (rparam);
2028 return True;
2029 }
2030
2031
2032
2033
2034
2035
2036
2037
2038 static int
2039 interpret_long_filename (int level, char *p, file_info * finfo)
2040 {
2041 extern file_info const def_finfo;
2042
2043 if (finfo)
2044 memcpy (finfo, &def_finfo, sizeof (*finfo));
2045
2046 switch (level)
2047 {
2048 case 1:
2049 if (finfo)
2050 {
2051
2052 finfo->ctime = make_unix_date2 (p + 4);
2053 finfo->atime = make_unix_date2 (p + 8);
2054 finfo->mtime = make_unix_date2 (p + 12);
2055 finfo->size = IVAL (p, 16);
2056 finfo->mode = CVAL (p, 24);
2057 pstrcpy (finfo->name, p + 27);
2058 }
2059 return (28 + CVAL (p, 26));
2060
2061 case 2:
2062 if (finfo)
2063 {
2064
2065 finfo->ctime = make_unix_date2 (p + 4);
2066 finfo->atime = make_unix_date2 (p + 8);
2067 finfo->mtime = make_unix_date2 (p + 12);
2068 finfo->size = IVAL (p, 16);
2069 finfo->mode = CVAL (p, 24);
2070 pstrcpy (finfo->name, p + 31);
2071 }
2072 return (32 + CVAL (p, 30));
2073
2074
2075 case 3:
2076 if (finfo)
2077 {
2078
2079 finfo->ctime = make_unix_date2 (p + 8);
2080 finfo->atime = make_unix_date2 (p + 12);
2081 finfo->mtime = make_unix_date2 (p + 16);
2082 finfo->size = IVAL (p, 20);
2083 finfo->mode = CVAL (p, 28);
2084 pstrcpy (finfo->name, p + 33);
2085 }
2086 return (SVAL (p, 4) + 4);
2087
2088 case 4:
2089 if (finfo)
2090 {
2091
2092 finfo->ctime = make_unix_date2 (p + 8);
2093 finfo->atime = make_unix_date2 (p + 12);
2094 finfo->mtime = make_unix_date2 (p + 16);
2095 finfo->size = IVAL (p, 20);
2096 finfo->mode = CVAL (p, 28);
2097 pstrcpy (finfo->name, p + 37);
2098 }
2099 return (SVAL (p, 4) + 4);
2100
2101 case 260:
2102 if (finfo)
2103 {
2104 int ret = SVAL (p, 0);
2105 int namelen;
2106 p += 4;
2107 p += 4;
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124 finfo->ctime = interpret_long_date (p);
2125 p += 8;
2126 finfo->atime = interpret_long_date (p);
2127 p += 8;
2128 finfo->mtime = interpret_long_date (p);
2129 p += 8;
2130 p += 8;
2131 finfo->size = IVAL (p, 0);
2132 p += 8;
2133 p += 8;
2134 finfo->mode = CVAL (p, 0);
2135 p += 4;
2136 namelen = IVAL (p, 0);
2137 p += 4;
2138 p += 4;
2139 p += 2;
2140 p += 24;
2141 StrnCpy (finfo->name, p, namelen);
2142 return (ret);
2143 }
2144 return (SVAL (p, 0));
2145 }
2146
2147 DEBUG (1, ("Unknown long filename format %d\n", level));
2148 return (SVAL (p, 0));
2149 }
2150
2151
2152
2153
2154
2155 int
2156 cli_list (struct cli_state *cli, const char *Mask, uint16 attribute,
2157 void (*fn) (file_info *, const char *, void *), void *state)
2158 {
2159 int max_matches = 512;
2160
2161 int info_level = cli->protocol < PROTOCOL_NT1 ? 1 : 260;
2162 char *p, *p2;
2163 pstring mask;
2164 file_info finfo;
2165 int i;
2166 char *dirlist = NULL;
2167 int dirlist_len = 0;
2168 int total_received = -1;
2169 BOOL First = True;
2170 int ff_resume_key = 0;
2171 int ff_searchcount = 0;
2172 int ff_eos = 0;
2173 int ff_lastname = 0;
2174 int ff_dir_handle = 0;
2175 int loop_count = 0;
2176 char *rparam = NULL, *rdata = NULL;
2177 int param_len, data_len;
2178
2179 uint16 setup;
2180 pstring param;
2181
2182 pstrcpy (mask, Mask);
2183
2184 while (ff_eos == 0)
2185 {
2186 loop_count++;
2187 if (loop_count > 200)
2188 {
2189 DEBUG (0, ("Error: Looping in FIND_NEXT??\n"));
2190 break;
2191 }
2192
2193 param_len = 12 + strlen (mask) + 1;
2194
2195 if (First)
2196 {
2197 setup = TRANSACT2_FINDFIRST;
2198 SSVAL (param, 0, attribute);
2199 SSVAL (param, 2, max_matches);
2200 SSVAL (param, 4, 8 + 4 + 2);
2201 SSVAL (param, 6, info_level);
2202 SIVAL (param, 8, 0);
2203 pstrcpy (param + 12, mask);
2204 }
2205 else
2206 {
2207 setup = TRANSACT2_FINDNEXT;
2208 SSVAL (param, 0, ff_dir_handle);
2209 SSVAL (param, 2, max_matches);
2210 SSVAL (param, 4, info_level);
2211 SIVAL (param, 6, ff_resume_key);
2212 SSVAL (param, 10, 8 + 4 + 2);
2213 pstrcpy (param + 12, mask);
2214
2215 DEBUG (5, ("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
2216 ff_dir_handle, ff_resume_key, ff_lastname, mask));
2217 }
2218
2219 if (!cli_send_trans (cli, SMBtrans2, NULL, 0,
2220 -1, 0,
2221 &setup, 1, 0,
2222 param, param_len, 10,
2223 NULL, 0, cli->max_xmit
2224 ))
2225 {
2226 break;
2227 }
2228
2229 if (!cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len))
2230 {
2231
2232
2233 uint8 eclass;
2234 uint32 ecode;
2235 cli_error (cli, &eclass, &ecode, NULL);
2236 if (eclass != ERRSRV || ecode != ERRerror)
2237 break;
2238 msleep (100);
2239 continue;
2240 }
2241
2242 if (total_received == -1)
2243 total_received = 0;
2244
2245
2246 p = rparam;
2247 if (First)
2248 {
2249 ff_dir_handle = SVAL (p, 0);
2250 ff_searchcount = SVAL (p, 2);
2251 ff_eos = SVAL (p, 4);
2252 ff_lastname = SVAL (p, 8);
2253 }
2254 else
2255 {
2256 ff_searchcount = SVAL (p, 0);
2257 ff_eos = SVAL (p, 2);
2258 ff_lastname = SVAL (p, 6);
2259 }
2260
2261 if (ff_searchcount == 0)
2262 break;
2263
2264
2265 p = rdata;
2266
2267
2268 if (ff_lastname > 0)
2269 {
2270 switch (info_level)
2271 {
2272 case 260:
2273 ff_resume_key = 0;
2274 StrnCpy (mask, p + ff_lastname, data_len - ff_lastname);
2275 break;
2276 case 1:
2277 pstrcpy (mask, p + ff_lastname + 1);
2278 ff_resume_key = 0;
2279 break;
2280 }
2281 }
2282 else
2283 {
2284 pstrcpy (mask, "");
2285 }
2286
2287
2288 dirlist = Realloc (dirlist, dirlist_len + data_len);
2289
2290 if (!dirlist)
2291 {
2292 DEBUG (0, ("Failed to expand dirlist\n"));
2293 break;
2294 }
2295
2296
2297
2298 for (p2 = p, i = 0; i < (ff_searchcount - 1); i++)
2299 p2 += interpret_long_filename (info_level, p2, NULL);
2300 SSVAL (p2, 0, data_len - PTR_DIFF (p2, p));
2301
2302
2303 memcpy (dirlist + dirlist_len, p, data_len);
2304 dirlist_len += data_len;
2305
2306 total_received += ff_searchcount;
2307
2308 if (rdata)
2309 free (rdata);
2310 rdata = NULL;
2311 if (rparam)
2312 free (rparam);
2313 rparam = NULL;
2314
2315 DEBUG (3, ("received %d entries (eos=%d resume=%d)\n",
2316 ff_searchcount, ff_eos, ff_resume_key));
2317
2318 First = False;
2319 }
2320
2321 for (p = dirlist, i = 0; i < total_received; i++)
2322 {
2323 p += interpret_long_filename (info_level, p, &finfo);
2324 fn (&finfo, Mask, state);
2325 }
2326
2327
2328 if (dirlist)
2329 free (dirlist);
2330 return (total_received);
2331 }
2332
2333
2334
2335
2336
2337 BOOL
2338 cli_negprot (struct cli_state * cli)
2339 {
2340 char *p;
2341 int numprots;
2342 int plength;
2343
2344 memset (cli->outbuf, '\0', smb_size);
2345
2346
2347 for (plength = 0, numprots = 0;
2348 prots[numprots].name && prots[numprots].prot <= cli->protocol; numprots++)
2349 plength += strlen (prots[numprots].name) + 2;
2350
2351 set_message (cli->outbuf, 0, plength, True);
2352
2353 p = smb_buf (cli->outbuf);
2354 for (numprots = 0; prots[numprots].name && prots[numprots].prot <= cli->protocol; numprots++)
2355 {
2356 *p++ = 2;
2357 pstrcpy (p, prots[numprots].name);
2358 p += strlen (p) + 1;
2359 }
2360
2361 CVAL (cli->outbuf, smb_com) = SMBnegprot;
2362 cli_setup_packet (cli);
2363
2364 CVAL (smb_buf (cli->outbuf), 0) = 2;
2365
2366 cli_send_smb (cli);
2367 if (!cli_receive_smb (cli))
2368 return False;
2369
2370 show_msg (cli->inbuf);
2371
2372 if (CVAL (cli->inbuf, smb_rcls) != 0 || ((int) SVAL (cli->inbuf, smb_vwv0) >= numprots))
2373 {
2374 return (False);
2375 }
2376
2377 cli->protocol = prots[SVAL (cli->inbuf, smb_vwv0)].prot;
2378
2379
2380 if (cli->protocol >= PROTOCOL_NT1)
2381 {
2382
2383 cli->sec_mode = CVAL (cli->inbuf, smb_vwv1);
2384 cli->max_mux = SVAL (cli->inbuf, smb_vwv1 + 1);
2385 cli->max_xmit = IVAL (cli->inbuf, smb_vwv3 + 1);
2386 cli->sesskey = IVAL (cli->inbuf, smb_vwv7 + 1);
2387 cli->serverzone = SVALS (cli->inbuf, smb_vwv15 + 1) * 60;
2388
2389 cli->servertime = interpret_long_date (cli->inbuf + smb_vwv11 + 1);
2390 memcpy (cli->cryptkey, smb_buf (cli->inbuf), 8);
2391 cli->capabilities = IVAL (cli->inbuf, smb_vwv9 + 1);
2392 if (cli->capabilities & 1)
2393 {
2394 cli->readbraw_supported = True;
2395 cli->writebraw_supported = True;
2396 }
2397 }
2398 else if (cli->protocol >= PROTOCOL_LANMAN1)
2399 {
2400 cli->sec_mode = SVAL (cli->inbuf, smb_vwv1);
2401 cli->max_xmit = SVAL (cli->inbuf, smb_vwv2);
2402 cli->sesskey = IVAL (cli->inbuf, smb_vwv6);
2403 cli->serverzone = SVALS (cli->inbuf, smb_vwv10) * 60;
2404
2405 cli->servertime = make_unix_date (cli->inbuf + smb_vwv8);
2406 cli->readbraw_supported = ((SVAL (cli->inbuf, smb_vwv5) & 0x1) != 0);
2407 cli->writebraw_supported = ((SVAL (cli->inbuf, smb_vwv5) & 0x2) != 0);
2408 memcpy (cli->cryptkey, smb_buf (cli->inbuf), 8);
2409 }
2410 else
2411 {
2412
2413 cli->sec_mode = 0;
2414 cli->serverzone = TimeDiff (time (NULL));
2415 }
2416
2417 cli->max_xmit = MIN (cli->max_xmit, CLI_BUFFER_SIZE);
2418
2419 return True;
2420 }
2421
2422
2423
2424
2425
2426 BOOL
2427 cli_session_request (struct cli_state * cli, struct nmb_name * calling, struct nmb_name * called)
2428 {
2429 char *p;
2430 int len = 4;
2431
2432
2433 memcpy (&(cli->calling), calling, sizeof (*calling));
2434 memcpy (&(cli->called), called, sizeof (*called));
2435
2436
2437 p = cli->outbuf + len;
2438 name_mangle (cli->called.name, p, cli->called.name_type);
2439 len += name_len (p);
2440
2441
2442 p = cli->outbuf + len;
2443 name_mangle (cli->calling.name, p, cli->calling.name_type);
2444 len += name_len (p);
2445
2446
2447 _smb_setlen (cli->outbuf, len);
2448 CVAL (cli->outbuf, 0) = 0x81;
2449
2450 #ifdef WITH_SSL
2451 retry:
2452 #endif
2453
2454 cli_send_smb (cli);
2455 DEBUG (5, ("Sent session request\n"));
2456
2457 if (!cli_receive_smb (cli))
2458 return False;
2459
2460 if (CVAL (cli->inbuf, 0) == 0x84)
2461 {
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473 int port = (CVAL (cli->inbuf, 8) << 8) + CVAL (cli->inbuf, 9);
2474
2475 putip ((char *) &cli->dest_ip, cli->inbuf + 4);
2476
2477 close_sockets ();
2478 cli->fd = open_socket_out (SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
2479 if (cli->fd == -1)
2480 return False;
2481
2482 DEBUG (3, ("Retargeted\n"));
2483
2484 set_socket_options (cli->fd, user_socket_options);
2485
2486
2487 return cli_session_request (cli, calling, called);
2488 }
2489
2490 #ifdef WITH_SSL
2491 if (CVAL (cli->inbuf, 0) == 0x83 && CVAL (cli->inbuf, 4) == 0x8e)
2492 {
2493 if (!sslutil_fd_is_ssl (cli->fd))
2494 {
2495 if (sslutil_connect (cli->fd) == 0)
2496 goto retry;
2497 }
2498 }
2499 #endif
2500
2501 if (CVAL (cli->inbuf, 0) != 0x82)
2502 {
2503
2504 cli->rap_error = CVAL (cli->inbuf, 0);
2505 return False;
2506 }
2507 return (True);
2508 }
2509
2510
2511
2512
2513
2514 BOOL
2515 cli_connect (struct cli_state * cli, const char *host, struct in_addr * ip)
2516 {
2517 extern struct in_addr ipzero;
2518
2519 fstrcpy (cli->desthost, host);
2520
2521 if (!ip || ip_equal (*ip, ipzero))
2522 {
2523 if (!resolve_name (cli->desthost, &cli->dest_ip, 0x20))
2524 {
2525 return False;
2526 }
2527 if (ip)
2528 *ip = cli->dest_ip;
2529 }
2530 else
2531 {
2532 cli->dest_ip = *ip;
2533 }
2534
2535 if (cli->port == 0)
2536 cli->port = 139;
2537
2538 cli->fd = open_socket_out (SOCK_STREAM, &cli->dest_ip, cli->port, cli->timeout);
2539 if (cli->fd == -1)
2540 return False;
2541
2542 return True;
2543 }
2544
2545
2546
2547
2548
2549 struct cli_state *
2550 cli_initialise (struct cli_state *cli)
2551 {
2552 if (!cli)
2553 {
2554 cli = (struct cli_state *) malloc (sizeof (*cli));
2555 if (!cli)
2556 return NULL;
2557 ZERO_STRUCTP (cli);
2558 }
2559
2560 if (cli->initialised)
2561 {
2562 cli_shutdown (cli);
2563 }
2564
2565 ZERO_STRUCTP (cli);
2566
2567 cli->port = 0;
2568 cli->fd = -1;
2569 cli->cnum = -1;
2570 cli->pid = (uint16) getpid ();
2571 cli->mid = 1;
2572 cli->vuid = UID_FIELD_INVALID;
2573 cli->protocol = PROTOCOL_NT1;
2574 cli->timeout = 20000;
2575 cli->bufsize = CLI_BUFFER_SIZE + 4;
2576 cli->max_xmit = cli->bufsize;
2577 cli->outbuf = (char *) malloc (cli->bufsize);
2578 cli->inbuf = (char *) malloc (cli->bufsize);
2579 if (!cli->outbuf || !cli->inbuf)
2580 {
2581 return False;
2582 }
2583
2584 cli->initialised = 1;
2585
2586 return cli;
2587 }
2588
2589
2590
2591
2592 void
2593 cli_shutdown (struct cli_state *cli)
2594 {
2595 if (cli->outbuf)
2596 {
2597 free (cli->outbuf);
2598 }
2599 if (cli->inbuf)
2600 {
2601 free (cli->inbuf);
2602 }
2603 #ifdef WITH_SSL
2604 if (cli->fd != -1)
2605 sslutil_disconnect (cli->fd);
2606 #endif
2607 if (cli->fd != -1)
2608 close (cli->fd);
2609 memset (cli, 0, sizeof (*cli));
2610 }
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621 int
2622 cli_error (struct cli_state *cli, uint8 * eclass, uint32 * num, uint32 * nt_rpc_error)
2623 {
2624 int flgs2 = SVAL (cli->inbuf, smb_flg2);
2625 char rcls;
2626 int code;
2627
2628 if (eclass)
2629 *eclass = 0;
2630 if (num)
2631 *num = 0;
2632 if (nt_rpc_error)
2633 *nt_rpc_error = cli->nt_error;
2634
2635 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES)
2636 {
2637
2638 uint32 nt_err = IVAL (cli->inbuf, smb_rcls);
2639 if (num)
2640 *num = nt_err;
2641 DEBUG (10, ("cli_error: 32 bit codes: code=%08x\n", nt_err));
2642 if (!IS_BITS_SET_ALL (nt_err, 0xc0000000))
2643 return 0;
2644
2645 switch (nt_err & 0xFFFFFF)
2646 {
2647 case NT_STATUS_ACCESS_VIOLATION:
2648 return EACCES;
2649 case NT_STATUS_NO_SUCH_FILE:
2650 return ENOENT;
2651 case NT_STATUS_NO_SUCH_DEVICE:
2652 return ENODEV;
2653 case NT_STATUS_INVALID_HANDLE:
2654 return EBADF;
2655 case NT_STATUS_NO_MEMORY:
2656 return ENOMEM;
2657 case NT_STATUS_ACCESS_DENIED:
2658 return EACCES;
2659 case NT_STATUS_OBJECT_NAME_NOT_FOUND:
2660 return ENOENT;
2661 case NT_STATUS_SHARING_VIOLATION:
2662 return EBUSY;
2663 case NT_STATUS_OBJECT_PATH_INVALID:
2664 return ENOTDIR;
2665 case NT_STATUS_OBJECT_NAME_COLLISION:
2666 return EEXIST;
2667 }
2668
2669
2670 return EINVAL;
2671 }
2672
2673 rcls = CVAL (cli->inbuf, smb_rcls);
2674 code = SVAL (cli->inbuf, smb_err);
2675 if (rcls == 0)
2676 return 0;
2677
2678 if (eclass)
2679 *eclass = rcls;
2680 if (num)
2681 *num = code;
2682
2683 if (rcls == ERRDOS)
2684 {
2685 switch (code)
2686 {
2687 case ERRbadfile:
2688 return ENOENT;
2689 case ERRbadpath:
2690 return ENOTDIR;
2691 case ERRnoaccess:
2692 return EACCES;
2693 case ERRfilexists:
2694 return EEXIST;
2695 case ERRrename:
2696 return EEXIST;
2697 case ERRbadshare:
2698 return EBUSY;
2699 case ERRlock:
2700 return EBUSY;
2701 }
2702 }
2703 if (rcls == ERRSRV)
2704 {
2705 switch (code)
2706 {
2707 case ERRbadpw:
2708 return EPERM;
2709 case ERRaccess:
2710 return EACCES;
2711 case ERRnoresource:
2712 return ENOMEM;
2713 case ERRinvdevice:
2714 return ENODEV;
2715 case ERRinvnetname:
2716 return ENODEV;
2717 }
2718 }
2719
2720 return EINVAL;
2721 }
2722
2723 #if 0
2724
2725
2726
2727 void
2728 cli_sockopt (struct cli_state *cli, char *options)
2729 {
2730 set_socket_options (cli->fd, options);
2731 }
2732
2733
2734
2735
2736 uint16
2737 cli_setpid (struct cli_state *cli, uint16 pid)
2738 {
2739 uint16 ret = cli->pid;
2740 cli->pid = pid;
2741 return ret;
2742 }
2743 #endif
2744
2745
2746
2747
2748 BOOL
2749 cli_reestablish_connection (struct cli_state * cli)
2750 {
2751 struct nmb_name calling;
2752 struct nmb_name called;
2753 fstring dest_host;
2754 fstring share;
2755 fstring dev;
2756 BOOL do_tcon = False;
2757 int oldfd = cli->fd;
2758
2759 if (!cli->initialised || cli->fd == -1)
2760 {
2761 DEBUG (3, ("cli_reestablish_connection: not connected\n"));
2762 return False;
2763 }
2764
2765
2766
2767 if (cli->cnum != 0)
2768 {
2769 fstrcpy (share, cli->share);
2770 fstrcpy (dev, cli->dev);
2771 do_tcon = True;
2772 }
2773
2774 memcpy (&called, &(cli->called), sizeof (called));
2775 memcpy (&calling, &(cli->calling), sizeof (calling));
2776 fstrcpy (dest_host, cli->full_dest_host_name);
2777
2778 DEBUG (5, ("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
2779 nmb_namestr (&calling), nmb_namestr (&called),
2780 inet_ntoa (cli->dest_ip), cli->user_name, cli->domain));
2781
2782 cli->fd = -1;
2783
2784 if (cli_establish_connection (cli,
2785 dest_host, &cli->dest_ip,
2786 &calling, &called, share, dev, False, do_tcon))
2787 {
2788 if (cli->fd != oldfd)
2789 {
2790 if (dup2 (cli->fd, oldfd) == oldfd)
2791 {
2792 close (cli->fd);
2793 }
2794 }
2795 return True;
2796 }
2797 return False;
2798 }
2799
2800
2801
2802
2803 BOOL
2804 cli_establish_connection (struct cli_state * cli,
2805 char *dest_host, struct in_addr * dest_ip,
2806 struct nmb_name * calling, struct nmb_name * called,
2807 char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon)
2808 {
2809 DEBUG (5, ("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
2810 nmb_namestr (calling), nmb_namestr (called), inet_ntoa (*dest_ip),
2811 cli->user_name, cli->domain));
2812
2813
2814
2815 if ((!cli->initialised))
2816 {
2817 return False;
2818 }
2819
2820 if (cli->fd == -1)
2821 {
2822 if (!cli_connect (cli, dest_host, dest_ip))
2823 {
2824 DEBUG (1, ("cli_establish_connection: failed to connect to %s (%s)\n",
2825 nmb_namestr (calling), inet_ntoa (*dest_ip)));
2826 return False;
2827 }
2828 }
2829
2830 if (!cli_session_request (cli, calling, called))
2831 {
2832 DEBUG (1, ("failed session request\n"));
2833 if (do_shutdown)
2834 cli_shutdown (cli);
2835 return False;
2836 }
2837
2838 if (!cli_negprot (cli))
2839 {
2840 DEBUG (1, ("failed negprot\n"));
2841 if (do_shutdown)
2842 cli_shutdown (cli);
2843 return False;
2844 }
2845
2846 if (cli->pwd.cleartext || cli->pwd.null_pwd)
2847 {
2848 fstring passwd;
2849 int pass_len;
2850
2851 if (cli->pwd.null_pwd)
2852 {
2853
2854 passwd[0] = 0;
2855 pass_len = 1;
2856 }
2857 else
2858 {
2859
2860 pwd_get_cleartext (&(cli->pwd), passwd);
2861 pass_len = strlen (passwd);
2862 }
2863
2864
2865 if (!cli_session_setup (cli, cli->user_name, passwd, pass_len, NULL, 0, cli->domain))
2866 {
2867 DEBUG (1, ("failed session setup\n"));
2868 if (do_shutdown)
2869 {
2870 cli_shutdown (cli);
2871 }
2872 return False;
2873 }
2874 if (do_tcon)
2875 {
2876 if (!cli_send_tconX (cli, service, service_type, (char *) passwd, strlen (passwd)))
2877 {
2878 DEBUG (1, ("failed tcon_X\n"));
2879 if (do_shutdown)
2880 {
2881 cli_shutdown (cli);
2882 }
2883 return False;
2884 }
2885 }
2886 }
2887 else
2888 {
2889
2890 unsigned char nt_sess_pwd[24];
2891 unsigned char lm_sess_pwd[24];
2892
2893
2894 pwd_make_lm_nt_owf (&(cli->pwd), cli->cryptkey);
2895 pwd_get_lm_nt_owf (&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
2896
2897
2898 if (!cli_session_setup (cli, cli->user_name,
2899 (char *) lm_sess_pwd, sizeof (lm_sess_pwd),
2900 (char *) nt_sess_pwd, sizeof (nt_sess_pwd), cli->domain))
2901 {
2902 DEBUG (1, ("failed session setup\n"));
2903 if (do_shutdown)
2904 cli_shutdown (cli);
2905 return False;
2906 }
2907
2908 if (do_tcon)
2909 {
2910 if (!cli_send_tconX (cli, service, service_type,
2911 (char *) nt_sess_pwd, sizeof (nt_sess_pwd)))
2912 {
2913 DEBUG (1, ("failed tcon_X\n"));
2914 if (do_shutdown)
2915 cli_shutdown (cli);
2916 return False;
2917 }
2918 }
2919 }
2920
2921 if (do_shutdown)
2922 cli_shutdown (cli);
2923
2924 return True;
2925 }
2926
2927
2928
2929
2930
2931 BOOL
2932 cli_chkpath (struct cli_state * cli, char *path)
2933 {
2934 pstring path2;
2935 char *p;
2936
2937 safe_strcpy (path2, path, sizeof (pstring) - 1);
2938 trim_string (path2, NULL, "\\");
2939 if (!*path2)
2940 *path2 = '\\';
2941
2942 memset (cli->outbuf, '\0', smb_size);
2943 set_message (cli->outbuf, 0, 4 + strlen (path2), True);
2944 SCVAL (cli->outbuf, smb_com, SMBchkpth);
2945 SSVAL (cli->outbuf, smb_tid, cli->cnum);
2946 cli_setup_packet (cli);
2947 p = smb_buf (cli->outbuf);
2948 *p++ = 4;
2949 safe_strcpy (p, path2, strlen (path2));
2950
2951 cli_send_smb (cli);
2952 if (!cli_receive_smb (cli))
2953 {
2954 return False;
2955 }
2956
2957 if (cli_error (cli, NULL, NULL, NULL))
2958 return False;
2959
2960 return True;
2961 }
2962
2963 #if 0
2964
2965
2966
2967 BOOL
2968 cli_message_start (struct cli_state * cli, char *host, char *username, int *grp)
2969 {
2970 char *p;
2971
2972
2973 memset (cli->outbuf, '\0', smb_size);
2974 set_message (cli->outbuf, 0, 0, True);
2975 CVAL (cli->outbuf, smb_com) = SMBsendstrt;
2976 SSVAL (cli->outbuf, smb_tid, cli->cnum);
2977 cli_setup_packet (cli);
2978
2979 p = smb_buf (cli->outbuf);
2980 *p++ = 4;
2981 pstrcpy (p, username);
2982 p = skip_string (p, 1);
2983 *p++ = 4;
2984 pstrcpy (p, host);
2985 p = skip_string (p, 1);
2986
2987 set_message (cli->outbuf, 0, PTR_DIFF (p, smb_buf (cli->outbuf)), False);
2988
2989 cli_send_smb (cli);
2990
2991 if (!cli_receive_smb (cli))
2992 {
2993 return False;
2994 }
2995
2996 if (cli_error (cli, NULL, NULL, NULL))
2997 return False;
2998
2999 *grp = SVAL (cli->inbuf, smb_vwv0);
3000
3001 return True;
3002 }
3003
3004
3005
3006
3007
3008 BOOL
3009 cli_message_text (struct cli_state * cli, char *msg, int len, int grp)
3010 {
3011 char *p;
3012
3013 memset (cli->outbuf, '\0', smb_size);
3014 set_message (cli->outbuf, 1, len + 3, True);
3015 CVAL (cli->outbuf, smb_com) = SMBsendtxt;
3016 SSVAL (cli->outbuf, smb_tid, cli->cnum);
3017 cli_setup_packet (cli);
3018
3019 SSVAL (cli->outbuf, smb_vwv0, grp);
3020
3021 p = smb_buf (cli->outbuf);
3022 *p = 1;
3023 SSVAL (p, 1, len);
3024 memcpy (p + 3, msg, len);
3025 cli_send_smb (cli);
3026
3027 if (!cli_receive_smb (cli))
3028 {
3029 return False;
3030 }
3031
3032 if (cli_error (cli, NULL, NULL, NULL))
3033 return False;
3034
3035 return True;
3036 }
3037
3038
3039
3040
3041 BOOL
3042 cli_message_end (struct cli_state * cli, int grp)
3043 {
3044 memset (cli->outbuf, '\0', smb_size);
3045 set_message (cli->outbuf, 1, 0, True);
3046 CVAL (cli->outbuf, smb_com) = SMBsendend;
3047 SSVAL (cli->outbuf, smb_tid, cli->cnum);
3048
3049 SSVAL (cli->outbuf, smb_vwv0, grp);
3050
3051 cli_setup_packet (cli);
3052
3053 cli_send_smb (cli);
3054
3055 if (!cli_receive_smb (cli))
3056 {
3057 return False;
3058 }
3059
3060 if (cli_error (cli, NULL, NULL, NULL))
3061 return False;
3062
3063 return True;
3064 }
3065 #endif
3066
3067 #if 0
3068
3069
3070
3071 BOOL
3072 cli_dskattr (struct cli_state * cli, int *bsize, int *total, int *avail)
3073 {
3074 memset (cli->outbuf, '\0', smb_size);
3075 set_message (cli->outbuf, 0, 0, True);
3076 CVAL (cli->outbuf, smb_com) = SMBdskattr;
3077 SSVAL (cli->outbuf, smb_tid, cli->cnum);
3078 cli_setup_packet (cli);
3079
3080 cli_send_smb (cli);
3081 if (!cli_receive_smb (cli))
3082 {
3083 return False;
3084 }
3085
3086 *bsize = SVAL (cli->inbuf, smb_vwv1) * SVAL (cli->inbuf, smb_vwv2);
3087 *total = SVAL (cli->inbuf, smb_vwv0);
3088 *avail = SVAL (cli->inbuf, smb_vwv3);
3089
3090 return True;
3091 }
3092 #endif